slimxmpp 线程认证

Posted

技术标签:

【中文标题】slimxmpp 线程认证【英文标题】:sleekxmpp threaded authentication 【发布时间】:2012-03-22 01:54:50 【问题描述】:

所以...我有一个像这样的简单聊天客户端:

class ChatClient(sleekxmpp.ClientXMPP):
    def __init__(self, jid, password, server):
        sleekxmpp.ClientXMPP.__init__(self, jid, password, ssl=True)

        self.add_event_handler("session_start", self.start)

        self.register_plugin('xep_0030')
        self.register_plugin('xep_0004')
        self.register_plugin('xep_0060')
        self.register_plugin('xep_0199')

        self.ssl_version = ssl.PROTOCOL_SSLv3
        self.connected = self.connect()
        if self.connected:
            self.process(threaded=True)


    def start(self, event):
        self.send_presence(priority = "-9001")
        self.get_roster(blocking = True, timeout = 3)

    def message(self, targets, msg):
        for target in targets:
            self.send_message(target, msg)

我有一个“验证”功能来确保您输入您的用户名/密码正确:

def authenticate(username, password, server):
    xmppuser = username + '@' + server
    passTester = ChatClient(xmppuser, password)

    passTester.disconnect(wait = True)
    authenticated = passTester.authenticated
    return authenticated

现在,问题出现在我将聊天客户端作为线程的地方,我遇到了在服务器有机会实际连接之前尝试检查 ChatClient.authenticated 的情况。如您所见,我尝试在断开连接时“等待”,但发送队列中没有任何内容,因此它立即断开连接。

我尝试过的另一种方法是:

def authenticate(username, password, server):
    xmppuser = username + '@' + server
    passTester = ChatClient(xmppuser, password)

    passTester.message('bogusName', 'ladfhkjdglkhjdfg')
    passTester.disconnect(wait = True)
    authenticated = passTester.authenticated
    return authenticated

现在我发送了一条虚假消息,断开连接呼叫需要等待。当我使用此代码输入正确的用户名/密码时,断开连接等待发送消息(这涉及等待真正的连接),不发送任何内容,并且 ChatClient.authenticated 设置为 True!

不幸的是,当我输入错误的用户名/密码时,消息永远不会发送,并且 disconnect(wait=True) 永远不会断开连接,因为消息永远不会发送。

还有其他人有更合适的“身份验证”方式吗?

【问题讨论】:

【参考方案1】:

这是将.authenticated 和相关字段更改为threading.Event 对象的一个​​很好的理由,这样您就可以在这种情况下使用wait(),但我不确定这会对现有用户造成多大的破坏代码。

但除了修改 SleekXMPP,您需要做的是等待某些事件触发。例如,如果您的客户端成功通过身份验证,那么将有一个session_start 事件(我可能会在以后添加一个auth_success 或类似事件)。同样,如果单一机制的身份验证失败,则会出现failed_auth 事件。如果根本没有任何身份验证方法成功(这是您感兴趣的),将会有一个no_auth 事件。

因此您可以为这些事件添加处理程序,并让这些处理程序将令牌放入队列中,然后等待所需的令牌到达。

class ChatClient(ClientXMPP):
    def __init__(self, ...):
        ...
        self.auth_queue = queue.Queue()
        self.add_event_handler('no_auth', self.failed)

    def start(self, event):
        self.auth_queue.put('success')
        ...

    def failed(self, event):
        self.auth_queue.put('failed')


def authenticate(username, password, server):
    xmppuser = username + '@' + server
    passTester = ChatClient(xmppuser, password)
    try:
        result = passTester.auth_queue.get(timeout=10)
    except queue.Empty:
        result = 'failed'
    passTester.disconnect()
    return result == 'success'

不要忘记,我们在sslough@conference.jabber.org 也有聊天室。

-- 兰斯

【讨论】:

谢谢你,我正在努力寻找一个 irc 频道。我想我没有足够的咖啡来认为你会有一个 xmpp 房间。我会在明天早上回去工作时测试解决方案并给你一个接受。

以上是关于slimxmpp 线程认证的主要内容,如果未能解决你的问题,请参考以下文章

java多线程的使用场景,大厂面试必备技能

python工程师必备:生成可执行文件进程线程协程数据处理

mysql 架构简介

在线认证机构,无法选择。

MySql知识体系总结(2021版)

java学习必备精选文章50篇:多线程函数式编程