SleekXMPP (Slixmpp) 服务器组件没有收到来自 ejabberd 的所有 MUC 消息
SleekXMPP (Slixmpp) Server Component not receiving all MUC messages from ejabberd
我们想为 ejabberd 构建一个简单的服务器组件,它接收发送到 MUC 房间的所有消息(我们有很多房间和新的一直在创建),并且在处理其中一些消息后,执行一些操作。
我们不希望我们的服务器组件像机器人一样行事,所以我们不希望它回复消息或类似的事情,我们只希望它接收所有消息的副本以便处理一些其中
为此,我们已按照此处提供的教程进行操作:https://sleekxmpp.readthedocs.io/en/latest/getting_started/component.html
问题是该组件似乎只接收到部分消息(大约 5 个中的 1 个)。
此外,我们观察到一个奇怪的行为:消息传递似乎是 "exclusive",这意味着消息要么传递给连接到房间的客户端,要么传递给服务器组件,说实话这很奇怪.换句话说,5 条消息中有 1 条被传送到服务器组件,其他 4 条消息照常传送到客户端。
这是我们的组件代码(我们已经尝试使用 sleekxmpp 和 slixmpp,但我们总是有相同的行为):
import sys
import logging
#import sleekxmpp
#from sleekxmpp.componentxmpp import ComponentXMPP
import slixmpp
from slixmpp.componentxmpp import ComponentXMPP
if sys.version_info < (3, 0):
from sleekxmpp.util.misc_ops import setdefaultencoding
setdefaultencoding('utf8')
else:
raw_input = input
class NotificationsComponent(ComponentXMPP):
def __init__(self):
ComponentXMPP.__init__(self, "muc.ourservice.it", "secret", "jabber.ourservice.it", 5233)
# add handler
self.add_event_handler("message", self.message)
#self.add_event_handler("groupchat_message", self.message)
def message(self, msg):
if msg['type'] == 'groupchat':
print('Received group chat message')
print(msg)
#msg.reply('Well received').send()
else:
print('Received another message')
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,format='%(levelname)-8s %(message)s')
xmpp = NotificationsComponent()
xmpp.register_plugin('xep_0030') # Service Discovery
#xmpp.register_plugin('xep_0004') # Data Forms
#xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
#xmpp.register_plugin('xep_0045') # MUC
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
xmpp.process()
这是我们的 ejabberd 18.03 配置的片段:
listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
starttls: true
certfile: 'CERTFILE'
protocol_options: 'TLSOPTS'
## dhfile: 'DHFILE'
## ciphers: 'CIPHERS'
##
## To enforce TLS encryption for client connections,
## use this instead of the "starttls" option:
##
starttls_required: true
##
## Stream compression
##
zlib: true
##
max_stanza_size: 65536
shaper: none
access: c2s
-
port: 5280
ip: "::"
module: ejabberd_http
request_handlers:
"/admin": ejabberd_web_admin
"/bosh": mod_bosh
#request_handlers:
# "/ws": ejabberd_http_ws
# "/bosh": mod_bosh
# "/api": mod_http_api
## "/pub/archive": mod_http_fileserver
web_admin: true
http_bind: true
## register: true
captcha: false
certfile: 'CERTFILE'
tls: true
-
port: 5233
ip: "::"
module: ejabberd_service
access: all
privilege_access:
message: "outgoing"
password: "secret"
shaper: none
我们也尝试过使用访问权限,privilege_access 和类似的东西,但没有运气。
你知道是什么导致了这种奇怪的行为吗?是否应该启用任何特定的插件或模块?
当然,我们在 sleekxmpp 和 ejabberd 上都启用了调试日志,但我们没有看到任何错误,只是缺少消息。
我们又做了一项测试。即使使用 slixmpp 存储库中可用的官方 "echo component" 示例,我们也会遇到同样的问题。所以看起来我们的服务器有问题,可能是消息路由部分,我们不知道。
谢谢
我认为你在这里混合了一些东西。您在此处创建的组件似乎作为外部组件连接到 ejabber(参见 https://xmpp.org/extensions/xep-0114.html or https://xmpp.org/extensions/xep-0225.html) judging from http://sleekxmpp.com/getting_started/component.html,这意味着 ejabber(似乎至少)将一些消息路由到它的内部组件,将一些消息路由到您的(外部)组件。这可以解释为什么您的组件仅接收某些消息。
您有两个选择:
- 使用 SleekXMPP 但以普通用户身份连接(您可以使用 "bot" 示例并简单地监听消息而不响应)
- 创建专用 component/handler within ejabberd,它将接收所有消息并相应地处理它们。
两种选择各有利弊:
- client-in-room - 更容易(对你来说,似乎)开发,但需要不断连接并且如果连接断开可能会丢失一些消息
- ejabberd 中的专用处理程序 - 很可能更难实现。
原来我完全误解了Jabber外部组件的用途。
我原本希望收到 ejabberd 中发生的所有事件的 "copy",但我错了。
为了达到我预期的结果,我使用了一个名为 "mod_post_log" 的模块,它为用户发送的每条消息发送一个 HTTP 请求。这对我有用。
我们想为 ejabberd 构建一个简单的服务器组件,它接收发送到 MUC 房间的所有消息(我们有很多房间和新的一直在创建),并且在处理其中一些消息后,执行一些操作。
我们不希望我们的服务器组件像机器人一样行事,所以我们不希望它回复消息或类似的事情,我们只希望它接收所有消息的副本以便处理一些其中
为此,我们已按照此处提供的教程进行操作:https://sleekxmpp.readthedocs.io/en/latest/getting_started/component.html
问题是该组件似乎只接收到部分消息(大约 5 个中的 1 个)。
此外,我们观察到一个奇怪的行为:消息传递似乎是 "exclusive",这意味着消息要么传递给连接到房间的客户端,要么传递给服务器组件,说实话这很奇怪.换句话说,5 条消息中有 1 条被传送到服务器组件,其他 4 条消息照常传送到客户端。
这是我们的组件代码(我们已经尝试使用 sleekxmpp 和 slixmpp,但我们总是有相同的行为):
import sys
import logging
#import sleekxmpp
#from sleekxmpp.componentxmpp import ComponentXMPP
import slixmpp
from slixmpp.componentxmpp import ComponentXMPP
if sys.version_info < (3, 0):
from sleekxmpp.util.misc_ops import setdefaultencoding
setdefaultencoding('utf8')
else:
raw_input = input
class NotificationsComponent(ComponentXMPP):
def __init__(self):
ComponentXMPP.__init__(self, "muc.ourservice.it", "secret", "jabber.ourservice.it", 5233)
# add handler
self.add_event_handler("message", self.message)
#self.add_event_handler("groupchat_message", self.message)
def message(self, msg):
if msg['type'] == 'groupchat':
print('Received group chat message')
print(msg)
#msg.reply('Well received').send()
else:
print('Received another message')
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,format='%(levelname)-8s %(message)s')
xmpp = NotificationsComponent()
xmpp.register_plugin('xep_0030') # Service Discovery
#xmpp.register_plugin('xep_0004') # Data Forms
#xmpp.register_plugin('xep_0060') # PubSub
xmpp.register_plugin('xep_0199') # XMPP Ping
#xmpp.register_plugin('xep_0045') # MUC
# Connect to the XMPP server and start processing XMPP stanzas.
xmpp.connect()
xmpp.process()
这是我们的 ejabberd 18.03 配置的片段:
listen:
-
port: 5222
ip: "::"
module: ejabberd_c2s
starttls: true
certfile: 'CERTFILE'
protocol_options: 'TLSOPTS'
## dhfile: 'DHFILE'
## ciphers: 'CIPHERS'
##
## To enforce TLS encryption for client connections,
## use this instead of the "starttls" option:
##
starttls_required: true
##
## Stream compression
##
zlib: true
##
max_stanza_size: 65536
shaper: none
access: c2s
-
port: 5280
ip: "::"
module: ejabberd_http
request_handlers:
"/admin": ejabberd_web_admin
"/bosh": mod_bosh
#request_handlers:
# "/ws": ejabberd_http_ws
# "/bosh": mod_bosh
# "/api": mod_http_api
## "/pub/archive": mod_http_fileserver
web_admin: true
http_bind: true
## register: true
captcha: false
certfile: 'CERTFILE'
tls: true
-
port: 5233
ip: "::"
module: ejabberd_service
access: all
privilege_access:
message: "outgoing"
password: "secret"
shaper: none
我们也尝试过使用访问权限,privilege_access 和类似的东西,但没有运气。
你知道是什么导致了这种奇怪的行为吗?是否应该启用任何特定的插件或模块?
当然,我们在 sleekxmpp 和 ejabberd 上都启用了调试日志,但我们没有看到任何错误,只是缺少消息。
我们又做了一项测试。即使使用 slixmpp 存储库中可用的官方 "echo component" 示例,我们也会遇到同样的问题。所以看起来我们的服务器有问题,可能是消息路由部分,我们不知道。
谢谢
我认为你在这里混合了一些东西。您在此处创建的组件似乎作为外部组件连接到 ejabber(参见 https://xmpp.org/extensions/xep-0114.html or https://xmpp.org/extensions/xep-0225.html) judging from http://sleekxmpp.com/getting_started/component.html,这意味着 ejabber(似乎至少)将一些消息路由到它的内部组件,将一些消息路由到您的(外部)组件。这可以解释为什么您的组件仅接收某些消息。
您有两个选择:
- 使用 SleekXMPP 但以普通用户身份连接(您可以使用 "bot" 示例并简单地监听消息而不响应)
- 创建专用 component/handler within ejabberd,它将接收所有消息并相应地处理它们。
两种选择各有利弊:
- client-in-room - 更容易(对你来说,似乎)开发,但需要不断连接并且如果连接断开可能会丢失一些消息
- ejabberd 中的专用处理程序 - 很可能更难实现。
原来我完全误解了Jabber外部组件的用途。
我原本希望收到 ejabberd 中发生的所有事件的 "copy",但我错了。
为了达到我预期的结果,我使用了一个名为 "mod_post_log" 的模块,它为用户发送的每条消息发送一个 HTTP 请求。这对我有用。