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

Posted

技术标签:

【中文标题】让 ejabberd 通知外部模块客户端存在更改【英文标题】:Getting ejabberd to notify an external module on client presence change 【发布时间】:2012-07-09 09:26:37 【问题描述】:

我在 jabber.domain.com 有一个 ejabberd 服务器,在 Presence.domain.com 有一个用 python 编写的 xmpp 组件(使用 slimxmpp)。

我希望组件在每次客户将其状态从可用更改为不可用时收到通知,反之亦然。

客户本身没有任何联系人。

目前,我已将我的客户设置为将他们可用的在线状态节发送到 admin@presence.domain.com,并且我确实收到了他们的在线/离线在线状态通知。但我觉得这不是正确的做法。

我希望客户端不会知道 Presence.domain.com 上的组件,他们只会连接到 jabber.domain.com,并且组件应该以某种方式从服务器收到有关客户端存在的通知。

有没有办法做到这一点? 我的组件设置是否正确?或者我应该考虑使用 xmpp 插件/模块/等..

谢谢

【问题讨论】:

据我所知,slickxmpp 是一个同步/阻塞库,它将阻塞通信直到它完成当前任务处理,这意味着当下一条消息到达您的 ejabberd 并转发到您的 slimxmpp 时,它将不得不等到它完成,因此会减慢您使用 ejabberd 的整体性能..您是如何解决这个问题的? 我放弃了 slimxmpp 组件配置并设置了 @ppolv 在他的回答中描述的 ejabberd 模块。现在,每当客户端连接/断开连接时,xmpp 服务器都会向外部服务发送消息。外部服务跟踪客户端的存在。 【参考方案1】:

为此编写一个自定义的 ejabberd 模块并不难。它需要在 ejabberd 中注册到存在更改挂钩,并在每个存在数据包上将通知路由到您的外部组件。

您的模块可以注册一对钩子“set_presence_hook”和“unset_presence_hook”,以便在用户开始/结束会话时得到通知。

如果您需要跟踪其他在线状态,还有一个钩子“c2s_update_presence”会在您的用户发送的任何在线数据包上触发。

不使用自定义模块的另一种可能性是使用共享名册。将 admin@presence.domain.com 添加到所有用户的共享名册中,但在这种情况下,他们会看到此项目反映在他们的名册上。

【讨论】:

谢谢,我会试试你的解决方案。当我到达它时,我会再次在这里发布。 将您的建议用于自定义模块。这对我们的用户来说是最透明的,而且问题最少(到目前为止;) @DoodyP : 我们可以在此聊天中扩展讨论吗chat.***.com/rooms/64981/ejabberd-with-mysql【参考方案2】:

组件可以像用户一样订阅用户的出席信息。用户也可以订阅组件的存在。您只需遵循通常的模式,即组件/用户发送subscribe 类型的<presence/>,用户/组件可以通过发送<presence/> 类型的<presence/> 来接受subscribed

您也可以让用户直接向组件发送出席信息。

无需编写自定义挂钩或创建代理用户。

【讨论】:

谢谢,这就是我现在正在做的事情,但感觉这种设置将客户端(用户)与服务器实现高度耦合。 这三个中哪个是“这个”? 对不起,这是“用户订阅组件的存在”。 如果您不需要,您没有必须同时进行这两项订阅。但是,如果您的组件变得可用/不可用,这将为您提供必要的最小耦合。

以上是关于让 ejabberd 通知外部模块客户端存在更改的主要内容,如果未能解决你的问题,请参考以下文章

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

翻译eJabberd 外部脚本的使用

在 ejabberd 中使用 mod_apns.erl 不应收到被阻止的用户的通知

ejabberd MUC 未通知新消息

Pubsub:标记为已读

使用 MySQL 和 ejabberd 进行高效的外部排班