XMPP Pubsub 问题使用 smack 订阅和发布

     2023-02-23     83

关键词:

【中文标题】XMPP Pubsub 问题使用 smack 订阅和发布【英文标题】:XMPP Pubsub problems subscribe and publish using smack 【发布时间】:2014-10-11 10:22:02 【问题描述】:

我正在尝试在我的应用程序中使用 Pubsub 模块,现在我正在尝试运行一些发布/订阅测试,但到目前为止没有结果。

在服务器端,我使用安装了 pubsub 的 ejabberd 2.1.11(或者至少看起来是这样)

mod_pubsub_odbc:     [access_createnode, pubsub_createnode,
pep_sendlast_offline, false,
last_item_cache, false,
plugins, ["flat", "hometree", "pep"]]

在客户端我已经能够创建节点,但我无法订阅它们。这是我的代码

XMPPConnection mycon = new XMPPTCPConnection(connectionConfiguration);

mycon.connect();
mycon.login("phantom_notifier", "phantom_notifier");

PubSubManager mgr = new PubSubManager(mycon);
LeafNode leaf = mgr.getNode("testNode2");

leaf.addItemEventListener(new ItemEventListener()

    @Override
    public void handlePublishedItems(ItemPublishEvent items) 
        //TODO
    
);
leaf.subscribe(mycon.getUser());

运行此代码后,我总是得到以下异常

java.io.EOFException: no more data available - expected end tag </stream:stream> to close start tag <stream:stream> from line 1, parser stopped on END_TAG seen ...</x></query></iq>... @1:3734
at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:3035)
at org.xmlpull.mxp1.MXParser.more(MXParser.java:3046)
at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1144)
at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
at org.jivesoftware.smack.tcp.PacketReader.parsePackets(PacketReader.java:279)
at org.jivesoftware.smack.tcp.PacketReader.access$000(PacketReader.java:47)
at org.jivesoftware.smack.tcp.PacketReader$1.run(PacketReader.java:81)

org.jivesoftware.smack.SmackException$NoResponseException
at org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:191)
at org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:175)
at org.jivesoftware.smackx.pubsub.PubSubManager.sendPubsubPacket(PubSubManager.java:303)
at org.jivesoftware.smackx.pubsub.Node.sendPubsubPacket(Node.java:443)
at org.jivesoftware.smackx.pubsub.Node.subscribe(Node.java:248)
at main.DBChangesReceiver.main(DBChangesReceiver.java:115)

无论我订阅哪个节点...

另一方面,每次我尝试发布消息时都没有收到任何错误,但检查日志我发现我的消息不正确。我用来发布消息的代码如下

leaf.publish(new PayloadItem<SimplePayload>("test" + System.currentTimeMillis(),
new SimplePayload("book", "pubsub:test:book",
"test book")));

在调试器中,我最后发送和接收的消息如下:

已发送消息

<iq id="BT97r-10" to="pubsub.myserver" type="set">
 <pubsub xmlns="http://jabber.org/protocol/pubsub">
   <publish node="testNode2">
    <item id="test1413022577642">test book</item>
  </publish>
</pubsub>

收到消息

<iq id="BT97r-10" to="phantom_notifier@myserver/Smack" from="pubsub.myserver" type="error">
 <pubsub xmlns="http://jabber.org/protocol/pubsub">
  <publish xmlns="http://jabber.org/protocol/pubsub">
    <item>test book</item>
  </publish>
 </pubsub>
 <error type="modify">
   <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
   <invalid-payload xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

现在我对那个无效的有效载荷一无所知,检查互联网上的文档我看不出有什么大的区别。

编辑

@Flow 建议后发送到服务器的包如下:

<iq id="XIaTx-11" to="pubsub.myserver" type="set">
 <pubsub xmlns="http://jabber.org/protocol/pubsub">
  <publish node="testNode2">
   <item id="test1413099855673">
     <book xmlns="pubsub:test:book">text book</book>
   </item>
  </publish>
 </pubsub>
</iq>

服务器没有发送响应,因为它似乎存在一些严重错误(与我尝试订阅时的注释相同):

oct 12, 2014 9:44:15 AM org.jivesoftware.smack.XMPPConnection callConnectionClosedOnErrorListener
Connection closed with error
java.io.EOFException: no more data available - expected end tag </stream:stream> to close start tag <stream:stream> from line 1, parser stopped on END_TAG seen ...</x></query></iq>... @1:3625
at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:3035)
at org.xmlpull.mxp1.MXParser.more(MXParser.java:3046)
at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1144)
at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
at org.jivesoftware.smack.tcp.PacketReader.parsePackets(PacketReader.java:279)
at org.jivesoftware.smack.tcp.PacketReader.access$000(PacketReader.java:47)
at org.jivesoftware.smack.tcp.PacketReader$1.run(PacketReader.java:81)

这里我有 ejabberd 错误日志(希望它有用)

=ERROR REPORT==== 2014-10-12 09:45:38 ===
** State machine <0.4880.3> terminating
** Last message in was route,
                    jid,[],"pubsub.myserver",[],[],
                     "pubsub.myserver",[],
                    jid,"phantom_notifier","myserver","Smack",
                     "phantom_notifier","myserver","Smack",
                    xmlelement,"iq",
                     ["type","error",
                      "from","pubsub.myserver",
                      "id","XIaTx-11"],
                     [xmlelement,"pubsub",
                       ["xmlns","http://jabber.org/protocol/pubsub"],
                       [xmlelement,"publish",
                         ["node","testNode2"],
                         [xmlelement,"item",
                           ["id","test1413099855673"],
                           [xmlelement,"book",
                             ["xmlns","pubsub:test:book"],
                             [xmlcdata,<<"text book">>]]]],
                      aborted,no_transaction]


** When State == session_established
**      Data  == state,
                 socket_state,gen_tcp,#Port<0.218148>,<0.4879.3>,
                 ejabberd_socket,#Ref<0.0.12.23022>,false,"2115632325",
                 sasl_state,"jabber","myserver",[],
                     #Fun<ejabberd_c2s.1.30334249>,
                     #Fun<ejabberd_c2s.2.32721014>,
                     #Fun<ejabberd_c2s.3.7052687>,cyrsasl_digest,
                     state,5,"3654209317","phantom_notifier",[],
                         #Fun<ejabberd_c2s.1.30334249>,
                         #Fun<ejabberd_c2s.3.7052687>,
                         ejabberd_auth_internal,"myserver",
                 c2s,c2s_shaper,false,true,false,false,
                 [verify_none,certfile,"/etc/ejabberd/ejabberd.pem"],
                 true,
                 jid,"phantom_notifier","myserver","Smack",
                     "phantom_notifier","myserver","Smack",
                 "phantom_notifier","myserver5","Smack",
                 1413,99937,977476,<0.4880.3>,
                 pres_t,1,
                 pres_f,1,
                 pres_a,1,
                 pres_i,0,
                 xmlelement,"presence",
                     ["id","XIaTx-9"],
                     [xmlelement,"status",[],
                          [xmlcdata,<<"Phantom on the phone">>],
                      xmlelement,"priority",[],[xmlcdata,<<"42">>]],
                 undefined,
                 2014,10,12,7,45,37,
                 false,
                 userlist,none,[],false,
                 c2s,ejabberd_auth_internal,
                 84,125,131,61,56127,
                 []
** Reason for termination =
** badxml,
    xmlelement,"iq",
        ["from","pubsub.myserver",
         "to","phantom_notifier@myserver/Smack",
         "type","error",
         "id","XIaTx-11"],
        [xmlelement,"pubsub",
             ["xmlns","http://jabber.org/protocol/pubsub"],
             [xmlelement,"publish",
                  ["node","testNode2"],
                  [xmlelement,"item",
                       ["id","test1413099855673"],
                       [xmlelement,"book",
                            ["xmlns","pubsub:test:book"],
                            [xmlcdata,<<"text book">>]]]],
         aborted,no_transaction],
    case_clause,aborted,no_transaction,
     [xml,element_to_string_nocatch,1,
      xml,'-element_to_string_nocatch/1-lc$^0/1-0-',1,
      xml,'-element_to_string_nocatch/1-lc$^0/1-0-',1,
      xml,element_to_string_nocatch,1,
      xml,element_to_string,1,
      xml,element_to_binary,1,
      ejabberd_c2s,send_element,2,
      ejabberd_c2s,handle_info,3],
[xml,element_to_string,1,
 xml,element_to_binary,1,
 ejabberd_c2s,send_element,2,
 ejabberd_c2s,handle_info,3,
 p1_fsm,handle_msg,10,
 proc_lib,init_p_do_apply,3]

我们可以看到的错误与客户端中给出的错误有关,即构造错误的 xml 元素。

【问题讨论】:

"查看日志我发现我的信息不正确。"您向我们展示了调试器发送的消息,既然您说它“不正确”,那么应该发送的预期消息是什么?另外,您使用哪个 Smack 版本? 您好,感谢您的回答,我使用的是 smack 4.0.4,我认为消息不正确(未正确发布),因为我在 error-type 节点内收到了 invalid-payload? .也许我错了?,消息发送成功? 【参考方案1】:

我认为问题在于item 只有文本,没有封闭的 XML 元素。这是 Smack 的 SimplePayload 类的一个不幸的设计问题。基本上你想替换

"test book"

"<book xmlns='pubsub:test:book'>text book</book>"

在构造 SimplePayload 时

【讨论】:

我尝试了您的建议,但现在我收到与尝试订阅节点时相同的错误。 java.io.EOFException: no more data available - expected end tag &lt;/stream:stream&gt; to close start tag &lt;stream:stream&gt; from line 1, parser stopped on END_TAG seen ...&lt;/x&gt;&lt;/query&gt;&lt;/iq&gt;... @1:3625 猜猜这意味着什么?我应该开始考虑我的服务器配置不正确吗?节点似乎创建正确。 我已经添加了 ejabberd 崩溃日志,以防万一可以对此有所了解:)

xmpp pubsub service(XEP-0060) 收到订阅请求后能否创建节点?

】xmpppubsubservice(XEP-0060)收到订阅请求后能否创建节点?【英文标题】:Canthexmpppubsubservice(XEP-0060)createanodewhenitreceivesasubscriberequest?【发布时间】:2011-10-2008:52:39【问题描述】:我们使用XMPPXEP-0060发布/订阅功能来构建通知系统。根... 查看详情

XMPP PubSub 检索节点的订阅者

】XMPPPubSub检索节点的订阅者【英文标题】:XMPPPubSubretrievenode\'ssubscribers【发布时间】:2013-12-0304:51:52【问题描述】:我有一个包含两个订阅者的PubSub节点:Joe和Mike。我想将它们作为订阅者列表以及何时进行检索<iqtype=\'get\'from... 查看详情

xmpp pubsub 理解

】xmpppubsub理解【英文标题】:xmpppubsubunderstanding【发布时间】:2009-10-1613:32:04【问题描述】:订阅者只会在订阅节点时收到内容,并且订阅者不会收到发布者发布的所有旧内容。它是否正确?我可以知道,我需要做什么才能让订... 查看详情

检索在 Smack XMPP 服务器中注册的用户的位置信息(无需订阅)

...ckXMPPServer(Withoutsubscription)【发布时间】:2013-04-1607:22:35【问题描述】:所以这是我的想法。我不想列出在XMPP服务器上注册的所有用户在我的位置半径内。这样我就可以添加(如果有兴趣)。我使用smack 查看详情

XMPP PubSub 通知是同时广播还是排队?

】XMPPPubSub通知是同时广播还是排队?【英文标题】:AreXMPPPubSubnotificationsbroadcastedsimultaneouslyorqueuelike?【发布时间】:2009-08-1805:57:59【问题描述】:我想知道xmpp发布-订阅功能是同时向所有订阅者发送通知(广播)还是在队列中发... 查看详情

xmpp pubsub:基于存在的交付

】xmpppubsub:基于存在的交付【英文标题】:xmpppubsub:presencebaseddelivery【发布时间】:2012-08-1000:47:51【问题描述】:“presence_based_delivery”根本无法在openfire上运行,还是我遗漏了什么?订阅者必须填写“订阅选项”吗?这就是我... 查看详情

Smack API中特定用户的所有发布-订阅项目列表?

...【发布时间】:2016-09-1208:16:10【问题描述】:我正在使用PUBSUB协议使用链接创建节点http://download.igniterealtime.org/smack/docs/latest/documentation/extensions/pubsu 查看详情

XMPP + 发布订阅 + ajaxpush

】XMPP+发布订阅+ajaxpush【英文标题】:XMPP+pubsub+ajaxpush【发布时间】:2011-04-2004:42:35【问题描述】:如果有数据库更新、群聊等,我需要实现ajax推送以实现实时更新。据我在网上研究后了解到,拥有彗星服务器、pubsubhubub和一些... 查看详情

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

】使用smack读取pubsub中的传入消息数据包【英文标题】:readincomingMessagepacketsinpubsubusingsmack【发布时间】:2012-12-0811:57:36【问题描述】:我正在尝试使用openfire服务器和asmack库来实现pubsub。我已将我的节点配置为subscribers必须获得p... 查看详情

使用 Smack 将带有 Payload 的项目发布到 Pubsub 节点

】使用Smack将带有Payload的项目发布到Pubsub节点【英文标题】:PublishinganitemwithPayloadtoaPubsubnodeusingSmack【发布时间】:2012-04-0215:40:09【问题描述】:我正在尝试使用Smack将带有有效负载的项目发布到pubsub节点,但到目前为止我还没... 查看详情

android中的XMPP连接使用smack

...XMPPconnectioninandroidusingsmack【发布时间】:2015-09-0110:00:38【问题描述】:我在运行代码时收到此错误。我正在使用smack3.1.0和smackx3.1.0以及smack的android扩展(smack-android-4.1.0-alpha6)09-0115:28:37.430:E/NativeCrypto(9558):s 查看详情

我在使用 smack 4.2 Openfire 创建 XMPP 客户端时遇到问题

】我在使用smack4.2Openfire创建XMPP客户端时遇到问题【英文标题】:I\'mhavingtroublecreatingXMPPclientusingsmack4.2Openfire【发布时间】:2017-04-1520:31:34【问题描述】:我想创建一个连接到我的Openfire服务器的简单XMPP客户端。我在运行代码时... 查看详情

如何为 xmpp 实现 smack

...】:howtoimplementsmackforxmpp【发布时间】:2020-12-1821:18:58【问题描述】:我正在尝试让我的android应用程序能够使用smack发送和接收xmpp消息,但它不起作用并且连接命令不返回。我看过几个代码示例,但Smack有新版本,语法也发生了... 查看详情

使用 Smack 接收自定义 XMPP 节

...ReceivecustomXMPPstanzaswithSmack【发布时间】:2013-08-1211:04:34【问题描述】:我正在尝试在消息包中接收XMPP自定义节。例如,<message...><custom_stanza><foo>wololo</foo><bar>haiooh</bar></cust 查看详情

如何使用 Smack XMPP 库创建 SSL 连接?

...nnectionusingtheSmackXMPPlibrary?【发布时间】:2009-02-1307:44:19【问题描述】:我正在构建一个充当XMPP客户端的小程序,并且我正在使用Smack库。现在,我要连接的服务器需要SSL(在Pidgin中我必须检查“强制旧(端口5223)SSL”)。我无... 查看详情

在 asmack 中将项目发送到 pubsub 节点

】在asmack中将项目发送到pubsub节点【英文标题】:Senditemtopubsubnodeinasmack【发布时间】:2013-04-1012:40:10【问题描述】:我正在开发一个安卓聊天客户端应用程序,我正在使用asmack来实现XMPP。我能够连接到我的XMPP服务器。我需要将... 查看详情

收到消息时通知 XMPP + Smack

...otifywhenreceivemessageXMPP+Smack【发布时间】:2015-11-0607:58:23【问题描述】:我只是在使用Smack和XMPP服务器,在接收来自其他用户的消息时遇到问题。我有2个用户,当用户1向用户2发送消息时,用户2会收到新消息的通知。在我的应用... 查看详情

XMPP 注销(Smack API)

...标题】:XMPPLogout(SmackAPI)【发布时间】:2011-08-0119:36:39【问题描述】:我正在使用SmackAPI连接到Openfire服务器。我已成功创建用户和登录用户,我的问题是我无法使用XMPPConnection.disconnect()进行注销,此后,在创建帐户或登录另一个... 查看详情