【发布时间】:2016-02-28 10:38:54
【问题描述】:
我有一个 Openfire 服务器为我的 Web 应用程序提供一堆群聊室 (MUC),它使用 Smack 库与 Openfire 交互。我正在尝试在应用程序中实现一项功能,该功能允许 MUC 所有者销毁他们拥有的房间。 Smack 的 MultiUserChat 类有一个方法——MultiUserChat.destroy(String, String)。很简单:
muc.destroy("This room isn't getting used", null);
以这种方式使用destroy 时,我没有收到任何编译错误或警告。但是,在运行时调用destroy 时会出现XMPPErrorException。这是堆栈跟踪的顶部:
org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: bad-request - modify
我阅读了 XMPP MUC 规范 (XEP-0045) 以了解为什么 MUC 销毁请求可能会返回 bad-request:modify。我知道如果销毁请求的发送者不是房间的所有者,则会发生禁止错误,但这不是正在发生的事情。我收到了一个错误的请求,而不是一个禁止的请求。规范没有说明为什么会在此处发生错误请求,错误也没有说明该请求的错误。
在 XMPP 规范中没有看到与错误请求错误相关的任何内容后,我启动了 Wireshark,这样我就可以看到实际的 XMPP 数据包在我的应用程序和 Openfire 服务器之间来回流动。除了一件事之外,一切看起来都基本符合预期:我的应用发送给 Openfire 的 MUC 销毁数据包在 <iq> 元素中没有 from 属性。
我的房间销毁请求:
<iq
to='theRoom@service.myserver.com'
id='Pk4om-935'
type='set'>
<query
xmlns='http://jabber.org/protocol/muc#owner'>
<destroy jid=''>
<reason>Nobody is using this room</reason>
</destroy>
</query>
</iq>
XEP-0045 房间销毁请求样本:
<iq from='crone1@shakespeare.lit/desktop'
id='begone'
to='heath@chat.shakespeare.lit'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#owner'>
<destroy jid='coven@chat.shakespeare.lit'>
<reason>Macbeth doth come.</reason>
</destroy>
</query>
</iq>
如您所见,我的请求没有from 属性,但除此之外两者几乎相同(destroy 的jid 属性是明确可选的,我不想使用它) .我深入研究了 Smack 代码,发现了销毁请求的构建位置,并且很明显它没有设置 from 属性。这部分代码中的注释指出from 通常是可选的,因此通常可以省略,这很可能是真的。 但是,我希望在销毁房间时需要from,因为只有房间所有者才能执行此操作。
以前有人用 Smack 摧毁过 Openfire MUC 房间吗?如果 Smack 总是使用 MultiUserChat.destroy(String, String) 方法生成错误请求,这似乎是该库的主要缺陷。但是,很可能我只是误解了如何使用该方法。任何 Smack/Openfire/XMPP 专家都可以在这里帮助我吗?
谢谢!
【问题讨论】:
-
对于客户端发送的节,'from' 属性在 c2s 会话中始终是可选的。所以这不可能是原因。然而,它很可能是用于“jid”值的空字符串。你不会通过阅读规范或客户端代码得到答案(尽管这是一个很好的开始),但通过调试服务器来查看是什么触发了错误请求。您使用哪个 Smack 版本?
-
您好,感谢您的回复。我使用核心 Smack 库和一堆扩展。它们都是 4.1.1 版或 4.1.0 版。我将尝试深入研究 Openfire 代码,看看为什么它会响应错误请求。感谢您的提示!