启用流管理 asmack android

19
我使用XEP-0198流管理时遇到了问题。
基本上,我想在Android上启用此功能,以解决当互联网随机断开连接时,服务器仍然保持客户端在线状态的消息丢失问题。
为了解决这个问题,我想使用XEP-0198,它使用请求和确认过程。您可以在这里找到更多信息。
基本上,我正在使用sm:3来实现这一点。问题是,当我设置``

``
XMPPConnection.DEBUG_ENABLED=true;

在 asmack 内部的日志中,我得到了 sm:3,但我无法通过在连接上添加任何 packetListner 来获取它。

这是 asmack 调试输出中的内容:

<r xmlns='urn:xmpp:sm:3'/><message from='test1@pinmessage.com/Smack' to='test1@pinmessage.com' id='CQUe6-5'><received xmlns='urn:xmpp:receipts' id='CQUe6-4'/></message><r xmlns='urn:xmpp:sm:3'/>

这是我从packetFilter得到的结果:

<message id="CQUe6-5" to="test1@pinmessage.com" from="test1@pinmessage.com/Smack"><received xmlns='urn:xmpp:receipts' id='CQUe6-4'/></message>

我曾通过查看ChatSecure和Yaxim的代码尝试自定义数据包过滤器,但是我不知道如何在我的代码中获取<r xmlns='urn:xmpp:sm:3'/> ,以便我可以将到目前为止接收到的数据包数量返回给服务器,以便服务器可以发送给我任何丢失的数据包。

我还配置了Provider Manager,并添加了以下代码:

        addSimplePacketExtension("sm", URN_SM_3);
        addSimplePacketExtension("r", URN_SM_3);
        addSimplePacketExtension("a", URN_SM_3);
        addSimplePacketExtension("enabled", URN_SM_3);
        addSimplePacketExtension("resumed", URN_SM_3);
        addSimplePacketExtension("failed", URN_SM_3);


private static final String URN_SM_3 = "urn:xmpp:sm:3";
    private static void addSimplePacketExtension(final String name, final String namespace) {
        Log.e("adding simple packet extension", namespace+"---"+name);
        ProviderManager.getInstance().addExtensionProvider(name, namespace,
                new PacketExtensionProvider() {
            public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
                StreamHandlingPacket packet = new StreamHandlingPacket(name, namespace);
                Log.e("Stream ahndling packet ","------>"+packet.toXML());
                int attributeCount = parser.getAttributeCount();
                for (int i = 0 ; i < attributeCount ; i++) {
                    packet.addAttribute(parser.getAttributeName(i), parser.getAttributeValue(i));
                }
                return (PacketExtension) packet;
            }
        });
    }


static class StreamHandlingPacket extends Packet {
        private String name;
        private String namespace;
        Map<String, String> attributes;

        StreamHandlingPacket(String name, String namespace) {
            this.name = name;
            this.namespace = namespace;
            attributes = Collections.emptyMap();
        }

        public void addAttribute(String name, String value) {
            if (attributes == Collections.EMPTY_MAP)
                attributes = new HashMap<String, String>();
            attributes.put(name, value);
        }

        public String getAttribute(String name) {
            return attributes.get(name);
        }

        public String getNamespace() {
            return namespace;
        }

        public String getElementName() {
            return name;
        }

        public String toXML() {
            StringBuilder buf = new StringBuilder();
            buf.append("<").append(getElementName());

            // TODO Xmlns??
            if (getNamespace() != null) {
                buf.append(" xmlns=\"").append(getNamespace()).append("\"");
            }
            for (String key : attributes.keySet()) {
                buf.append(" ").append(key).append("=\"").append(StringUtils.escapeForXML(attributes.get(key))).append("\"");
            }
            buf.append("/>");
            Log.e("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&","&&&&&&&&&&&&&&&&&&&&&&&&&&&&=>"+buf.toString());
            return buf.toString();
        }

    }

基本上我是通过查看聊天安全实现而得出这个想法的,但它扩展了UnkownPacket而不是Packet。我从这里得到了帮助。

我还看过类似于asmack git分支的代码,但无法理解如何实现它。

如果您已经用任何库(如聊天安全,yaxim或任何其他android XMPP客户端)以任何方式实现了它,请提供帮助。

3个回答

1

我建议使用运行在 Android 平台上并支持 XEP-198 流管理的 Smack 4.1。


1
有没有关于在Android中使用Smack 4.1和XEP 198的教程? - Tolgay Toklar
嗨@Flow,我们能否覆盖流管理以在需要时每次发送确认?我想在将消息插入数据库后发送流确认,但默认的流管理会在我收到消息时立即发送确认。提前致谢。 - Shayan Pourvatan

0

我无法为你提供解决方案,因为我遇到了类似的问题,但是我可以告诉你从第二个链接中得知UnknownPacket扩展了Packet并实现了PacketExtension,这就是为什么你必须将StreamHandlingPacket强制转换为(PacketExtension)在parseExtension方法的返回语句中。

当你发送<enable xmlns='urn:xmpp:sm:3' etc>时,你能否捕获XMPP服务器返回的<enabled xmlns='urn:xmpp:sm:3' etc> xml?如果可以,那就是你问题的开始。

让我们知道进展如何!


我无法获取<enabled ...>标签,这是主要问题,因为所有这些都在日志中打印出来,但在我的层面上,我无法获取它。 我可以获取所有其他<iq... <presence和<message标签,但无法获取我添加的扩展提供程序。 你有没有见过像yaxim或chat secure这样的其他客户端,他们已经实现了XEP-0198并使用aSmack。我认为他们根据自己的需求定制了aSmack。 你知道如何将smack补丁到aSmack或制作自己的定制aSmack吗? - Akhil Dad
很抱歉,您是正确的,我们试图做的事情是不可能的:http://community.igniterealtime.org/message/238413#238413 - dbar
但我可以看到一些客户已经实现了它。您可以在以下链接中检查ChatSecure和Yaximhttp://yaxim.org/blog/2014/01/30/yaxim-0-dot-8-7-stream-management-and-more/ https://github.com/devrandom/asmack/commit/5f8bee65064006ba6e479f2c515516f4670be1b5 https://github.com/guardianproject/ChatSecureAndroid/pull/116据我所知,他们也在使用aSmack。 - Akhil Dad
我添加了一个新的答案,其中包含你所需要的库 :) - dbar

0

我已经尝试将该库添加到我的构建路径中,但在身份验证时出现致命错误,因为该库可能发生了一些更改(身份验证可能已更改)。我只想知道如何修补该库,以便我可以根据自己的需求制作一个修补后的库。或者我需要查看yaxim实现细节和所有方法。 - Akhil Dad
你添加了libidn库吗? - dbar
现在我也添加了libidn,目前它正在工作。我将首先进行更多的测试。 - Akhil Dad
让我知道进展如何,到目前为止我一直无法恢复流,每次恢复后都会得到一个<失败>的响应。 - dbar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接