Smack android传入的onStanza与调试器不同

Posted

技术标签:

【中文标题】Smack android传入的onStanza与调试器不同【英文标题】:Smack android incoming onStanza is different from debugger 【发布时间】:2017-07-28 11:13:08 【问题描述】:

Windows 上的 Gajim 客户端和 smack 调试器返回这种节,与 xmpp 规范中的节相同。

<message id='aeb213' to='juliet@capulet.lit/chamber'>
  <result xmlns='urn:xmpp:mam:2' queryid='f27' id='28482-98726-73623'>
    <forwarded xmlns='urn:xmpp:forward:0'>
      <delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
      <message xmlns='jabber:client' from="witch@shakespeare.lit" to="macbeth@shakespeare.lit">
        <body>Hail to thee</body>
      </message>
    </forwarded>
  </result>
</message>

但在onStanza 中,它会返回这个:

<message to="juliet@capulet.lit/chamber" from="juliet@capulet.lit/chamber">
  <result xmlns="urn:xmpp:mam:0">
    <body>Hail to thee</body>
    <stanza-id/>
    <delay/>
    <archived/>
    <data/>
  </result>
</message>

你如何解决这个问题?以下是部分代码。

public class XmppServiceSmackImpl implements XmppService, StanzaListener, ConnectionListener 
    XmppServiceListener xmppServiceListener;
    Logger logger = Logger.getLogger(XmppServiceSmackImpl.class.getName());

    XMPPTCPConnection connection;
    String password;

    public XmppServiceSmackImpl(XmppServiceListener xmppServiceListener) 
        this.xmppServiceListener = xmppServiceListener;
    

    @Override
    public void setup(String jid, String password, String authMethod, String hostname, Integer port) 
        final String[] jidParts = jid.split("@");
        String[] serviceNameParts = jidParts[1].split("/");
        String serviceName = serviceNameParts[0];

        XMPPTCPConnectionConfiguration.Builder confBuilder = XMPPTCPConnectionConfiguration.builder()
                .setServiceName(serviceName)
                .setUsernameAndPassword(jidParts[0], password)
                .setConnectTimeout(3000)
                //.setDebuggerEnabled(true)
                .setSecurityMode(ConnectionConfiguration.SecurityMode.required);

        if (serviceNameParts.length>1)
            confBuilder.setResource(serviceNameParts[1]);
         else 
            confBuilder.setResource(Long.toHexString(Double.doubleToLongBits(Math.random())));
        
        if (hostname != null)
            confBuilder.setHost(hostname);
        
        if (port != null)
            confBuilder.setPort(port);
        
        if (trustedHosts.contains(hostname) || (hostname == null && trustedHosts.contains(serviceName)))
            confBuilder.setCustomSSLContext(UnsafeSSLContext.INSTANCE.getContext());
        
        XMPPTCPConnectionConfiguration connectionConfiguration = confBuilder.build();
        XMPPTCPConnection.setUseStreamManagementDefault(true);
        XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);
        connection = new XMPPTCPConnection(connectionConfiguration);

        // Disable automatic roster request
        Roster roster = Roster.getInstanceFor(connection);
        roster.setRosterLoadedAtLogin(false);
        roster.setSubscriptionMode(Roster.SubscriptionMode.manual);

        connection.addAsyncStanzaListener(this, null);
        connection.addConnectionListener(this);
        connection.addStanzaAcknowledgedListener(this);
    

    @Override
    public void processPacket(Stanza packet) throws SmackException.NotConnectedException 
        logger.log(Level.WARNING, "Received stanza: " + packet);
        this.xmppServiceListener.onStanza(packet);
      

【问题讨论】:

【参考方案1】:

属于 XEP-0280 在 SMACK 中,这是一个实验性功能。 你的 build.gradle 中需要额外的库

dependencies 
    compile "org.igniterealtime.smack:smack-android-extensions:4.2.0"

在你对 SMACK 做任何事情之前,你必须初始化实验功能:

new ExperimentalInitializer().initialize();

顺便说一下,provider 是一个类似于插件的节处理程序 当您想在客户端和服务器之间使用自定义节时。 您必须编写自己的提供程序以将其解析为 Message 对象下的扩展元素。 看看 ProviderManager。

【讨论】:

我升级到 4.2.0 并解决了这个问题,因为新添加了 mam 支持及其提供程序。但很高兴了解自定义提供程序

以上是关于Smack android传入的onStanza与调试器不同的主要内容,如果未能解决你的问题,请参考以下文章

使用 smack 读取 pubsub 中的传入消息数据包

Smack MUC 邀请

在 MainActivity android 中使用 smack API 与服务器连接

在 xmpp smack 库中收到两次消息

使用 smack 进行 android 文件传输

使用 Openfire 服务器和 XMPP(SMACK)客户端的 Android 聊天应用程序 [关闭]