如何使用 xmpp 和 Python xmpppy 发送多播消息(多个用户)(XEP-0033:扩展节寻址)

Posted

技术标签:

【中文标题】如何使用 xmpp 和 Python xmpppy 发送多播消息(多个用户)(XEP-0033:扩展节寻址)【英文标题】:How to send multicast message (multiple users) using xmpp and Python xmpppy (XEP-0033: Extended Stanza Addressing) 【发布时间】:2015-02-23 15:48:28 【问题描述】:

我正在使用 xmpppy http://xmpppy.sourceforge.net/ 发送 Jabber 通知,它适用于使用以下代码的单个目的地:

# pip install https://github.com/rochacbruno/xmpppy/tarball/master

import xmpp

JABBER_SETTINGS = "USERNAME": None, "PASSWORD": None, "DOMAIN": None, "RESOURCE": None    

def get_jabber_client():
    client = xmpp.Client(JABBER_SETTINGS.get('DOMAIN'))
    client.connect(server=(JABBER_SETTINGS.get('DOMAIN'), '5222'))
    client.auth(
        JABBER_SETTINGS.get('USERNAME'),
        JABBER_SETTINGS.get('PASSWORD'), 
        JABBER_SETTINGS.get('RESOURCE')
    )
    client.sendInitPresence()
    return client

def send_message(to, message):
    client = get_jabber_client()
    xmpp_message = xmpp.Message(to, message)
    client.send(xmpp_message)
    client.disconnect()

send_message("single.destination@domain.com", "Hello World!")

但现在我需要将消息发送到多个目的地,目前我正在这样做。

for users in list_of_users:
    send_message(user, "Hello World!")

这很好用,但每次我调用它都会启动身份验证过程并且需要很多时间。

我尝试创建一个客户端并使用同一个客户端发送消息。

def send_message(to, message):
    if isinstance(to, basestring):
        to = [to]
    assert isinstance(to, (list, tuple))
    client = get_jabber_client()
    for destination in to:
        xmpp_message = xmpp.Message(destination, message)
        client.send(xmpp_message)
    client.disconnect()

send_message(['user1...', 'user2...'], "Hello World!")

上面的代码有效,但只有列表中的第一个用户收到格式正确的消息,其他用户收到纯 XML 格式的消息。

我看到了这段代码(在 .net 中),提到了 XEP-0033:Extended Stanza Addressing http://forum.ag-software.net/thread/1482-Send-Message-To-all-users-in-contact-list

var addresses = new Addresses();
addresses.AddAddress(new Address
              
                  Type = Type.to,
                  Jid = "hildjj@jabber.org/Work",
                  Description = "Joe Hildebrand"
              );

addresses.AddAddress(new Address
        
            Type = Type.cc,
            Jid = "jer@jabber.org/Home",
            Description = "Jeremie Miller"
        );

var msg = new Matrix.Xmpp.Client.Message();

msg.Add(addresses);
msg.To = "multicast.jabber.org";
msg.Body = "Hello, world!";

builds the following Xml:

<message to='multicast.jabber.org'>
   <addresses xmlns='http://jabber.org/protocol/address'>
       <address type='to' jid='hildjj@jabber.org/Work' desc='Joe Hildebrand'/>
       <address type='cc' jid='jer@jabber.org/Home' desc='Jeremie Miller'/>
   </addresses>
   <body>Hello, world!</body>
</message>

但是我没有找到使用 xmpppy 在 Python 中执行相同操作的方法,关于如何使用 Python 构建多播节并将消息发送给多个用户的任何想法?

谢谢。

【问题讨论】:

【参考方案1】:

如果没有 XEP-0033,您或许可以完成这项工作。在这个循环中,你第一次覆盖了变量message的值,后面的消息就会变成乱码:

for destination in to:
    message = xmpp.Message(destination, message)
    client.send(message)

试试这个:

for destination in to:
    xmpp_message = xmpp.Message(destination, message)
    client.send(xmpp_message)

【讨论】:

我更正了变量名,但还是不行,我觉得还有别的。更好的方法是实施 XEP-0033。谢谢

以上是关于如何使用 xmpp 和 Python xmpppy 发送多播消息(多个用户)(XEP-0033:扩展节寻址)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 samck API、XMPP 接收聊天室消息

如何使用 Smack XMPP API 处理(失败的)登录尝试

如何使用 Facebook 登录 API 对 XMPP 用户进行身份验证?

如何在 Python 中使用 XMPP 客户端获得响应

如何使用 python-xmpp(和 gtalk)每 x 分钟向收件人发送一条消息?

如何使用 SleekXMPP 或 python 处理 XMPP 订阅我一般