如何在 Smack 中启用 XEP-0199?

Posted

技术标签:

【中文标题】如何在 Smack 中启用 XEP-0199?【英文标题】:How to enable the XEP-0199 in Smack? 【发布时间】:2014-05-30 10:24:45 【问题描述】:

我正在使用 aSmack。我的应用程序监听聊天室并对消息做出反应,但它从不发送消息。如果聊天室保持沉默一段时间,然后发送新消息,则应用程序不会收到更多消息。我进行了研究,我认为XEP-0199 是这里的解决方案。我看到@Flow(当前的 Smack 维护者)implemented it 和 the issue related 已关闭。

我认为我需要使用PingProvider,但我真的不知道如何将这个类与Connection联系起来。

如何启用XEP-0199?如何使用PingProvider


连接代码:

smack = Smackandroid.init(getActivity().getApplicationContext());
connection = new XMPPConnection(App.getServer());
connection.addConnectionListener(new ConnectionListener() 

    private final static String SMACK = "SMACK";

    @Override
    public void reconnectionSuccessful() 
        Log.i(SMACK , "reconnectionSuccessful");
    

    @Override
    public void reconnectionFailed(Exception e) 
        Log.i(SMACK, "reconnectionFailed", e);
    

    @Override
    public void reconnectingIn(int seconds) 
        Log.i(SMACK, "reconnectingIn " + seconds);
    

    @Override
    public void connectionClosedOnError(Exception e) 
        Log.i(SMACK, "connectionClosedOnError", e);
    

    @Override
    public void connectionClosed() 
        Log.i(SMACK, "connectionClosed");
    
);
connection.connect();
connection.login(user, password);

【问题讨论】:

【参考方案1】:

我手动解决了执行 ping 响应的问题:

connection.addPacketListener(new PacketListener() 

    @Override
    public void processPacket(Packet packet) 
        connection.sendPacket(new Pong((Ping) packet));
    
, new PacketFilter() 

    @Override
    public boolean accept(Packet packet) 
        return packet instanceof Ping;
    
);

【讨论】:

什么是乒乓球?你能解释一下吗? 似乎他们删除了Pong 类in this commit。不过现在Ping has a getPong() method,你可以试试。 当用户离线时我们如何管理我的意思是我们如何在按下按钮后手动停止 ping 管理器? 用于接收来自 FCM 的通知【参考方案2】:

为了防止用户断开您的会话

PingManager pm =  PingManager.getInstanceFor(MyApplication.connection) ;
    pm.setPingInterval(5) ;  // 5 sec
    pm.pingMyServer() ;
    pm.registerPingFailedListener(new PingFailedListener() 

        @Override
        public void pingFailed() 
            Log.e(TAG , "pingFailed") ;
        
    );

【讨论】:

我想指出,如果在移动连接上使用 5 秒的 ping 间隔,将很快耗尽设备电池。 有一个大问题,如果用户在没有先通知openfire的情况下离线,openfire会假设客户端收到了数据包,所以当他登录时不会再次发送它。用户 A 在线 用户 B 向 A 发送了 MUC 邀请 用户 A 在未通知 openfire 的情况下收到邀请之前已离线 用户 B 将假定 A 收到了邀请,并且邀请丢失了【参考方案3】:

XEP 0199 不是解决方案,Ping 用于检查服务器是否启动的天气。实际上,您将向服务器发送 ping。

现在就您的问题而言。向我显示您尝试发送的消息节。并检查聊天室是公共的还是私人的。您不能向私人聊天室发送消息。

答案已更新:

尝试使用此代码来检测消息接收

PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
        Network.connection.addPacketListener(new PacketListener() 
            public void processPacket(Packet packet) 
                Message message = (Message) packet;
                if (message.getBody() != null) 
                    String fromName = StringUtils.parseBareAddress(message.getFrom());
                    Log.i("XMPPClient", "Got text [" + message.getBody() + "] from [" + fromName + "]");
                   //recieve.setText(message.getBody());
                    /*messages.add(fromName + ":");
                    messages.add(message.getBody());*/
                    // Add the incoming message to the list view
                    item = new RowItem(R.drawable.billing, message.getBody());
                    adapter = new CustomListViewAdapter(getBaseContext(),
                            R.layout.list_item, rowItems);
                    rowItems.add(item);
                    //listView.setAdapter(adapter);
                
            
        , filter);

【讨论】:

我不想发送任何消息。我只想在很长一段时间内收到所有消息。但是当聊天室沉默了一会儿时,我似乎失去了连接,但我没有通过ConnectionListener 收到任何事件。在我的测试中,应用程序始终处于前台并且屏幕已打开。 我刚刚在我的问题中添加了它。【参考方案4】:

我调用了PingManager.getInstanceFor 方法来启用 XEP-0199 支持。

【讨论】:

以上是关于如何在 Smack 中启用 XEP-0199?的主要内容,如果未能解决你的问题,请参考以下文章

Facebook 聊天 tcp 连接如何保持活动状态?

如何在 ejabberd 服务器中启用流管理?

启用 IQProvider 时,Smack 无法识别 type="result" 节

如何在 Android 的 Smack 中接收文件?

如何在 Openfire 中使用 smack

如何在消息 asmack/smack 中添加其他数据?