如何允许 Ejabberd 外部 XMPP 组件代表用户发送存在数据包

Posted

技术标签:

【中文标题】如何允许 Ejabberd 外部 XMPP 组件代表用户发送存在数据包【英文标题】:How to allow Ejabberd external XMPP component to send presence packets on behalf of a user 【发布时间】:2016-02-05 14:02:59 【问题描述】:

我为 Ejabberd 编写了一个外部组件,但在尝试代表用户发送出席信息节时,我收到 400 错误。

组件的名称是 bot.domain.com,Ejabberd 中的主机名是 domain.com,我已将组件的“check_from”标志设置为 false。

下面是我试图代表用户从组件发送的出席信息节的示例:

<presence from="user@domain.com">
    <status>Test status</status>
    <show>dnd</show>
</presence>

这是 Ejabberd 返回的错误消息:

<presence type="error" to="user@domain.com">
    <status>Test status</status>
    <show>dnd</show>
    <error code="400" type="modify">
         <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</presence>

如果我在要发送的包中添加 to="user2@domain.com",则目标用户实际上会收到包。

如果我添加到 =“domain.com”,我不会再收到 400 错误,但不会向用户名册中的任何人广播存在。

实际的问题似乎是 Ejabberd 没有向用户名册中的每个人广播出席信息包。

知道我可能遗漏了什么,或者为什么在未指定“to”字段时出现 400 错误?

【问题讨论】:

【参考方案1】:

您不能从组件中代表用户广播名册存在情况。组件服务不加载用户名册。只有ejabberd_c2s 负责加载名册以进行广播。它还负责检查隐私列表和 XMPP 的许多重要功能。

附带说明,我不知道您希望使用该方法做什么,但您可以在 XMPP 中将存在与用户会话分开。用户首先在线是因为他在 XMPP 上打开了一个会话,其次是因为他发送了一个出席信息。通过为用户伪造从组件发送的出席信息,您不能保证该用户将打开会话。在那种情况下,整体行为肯定不会是你所期望的。

【讨论】:

感谢 Mickael,其目的是仅在用户浏览我们网站的特定部分时使用一个组件来更新用户的状态消息。正如您在上面指定的那样,使用标准 Ejabberd 安装无法做到这一点,因此唯一的方法是修改 ejabberd_service 模块以广播我们的组件代表用户发送的存在数据包。

以上是关于如何允许 Ejabberd 外部 XMPP 组件代表用户发送存在数据包的主要内容,如果未能解决你的问题,请参考以下文章

让 ejabberd 通知外部模块客户端存在更改

不允许任何所有者撤销创建房间/MUC 的用户的所有权 - Ejabberd XMPP

如何使用 XMPPHP 客户端创建 XMPP(ejabberd) 用户

如何在 ejabberd/XMPP 中获取所有在线用户的列表?

如何在 ejabberd 中的 xmpp 消息正文中附加自定义数据

Ejabberd 13.12 如何添加元素 XMPP 数据包?