потоковая аутентификация sleekxmpp

Итак... У меня есть простой чат-клиент:

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!

К сожалению, когда я ввожу неправильное имя пользователя/пароль, сообщение никогда не отправляется, а разъединение (wait=True) никогда не отключается, поскольку сообщение никогда не отправляется.

Есть ли у кого-нибудь более правильный способ «аутентификации»?


person odgrim    schedule 22.03.2012    source источник


Ответы (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'

Не забывайте, что у нас также есть чат по адресу [email protected].

-- Ланс

person Lance Stout    schedule 22.03.2012
comment
Спасибо за это, я сломал голову, пытаясь найти irc-канал. Думаю, мне не хватило кофе, чтобы подумать, что у тебя будет комната xmpp. Я протестирую решение и дам вам согласие, когда вернусь на работу завтра утром. - person odgrim; 22.03.2012