Вопрос по websocket, tornado, python – Торнадо: определить / отслеживать соединения веб-сокетов?

17

У меня есть базовый тест веб-сокета Торнадо:

import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web

class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print 'new connection'
        self.write_message("Hello World")

    def on_message(self, message):
        print 'message received %s' % message

    def on_close(self):
      print 'connection closed'


application = tornado.web.Application([
    (r'/ws', WSHandler),
])


if __name__ == "__main__":
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

Я хочу иметь возможность обрабатывать несколько соединений (что, кажется, уже делает), но также иметь возможность ссылаться на другие соединения. Я не вижу способа идентифицировать и отслеживать отдельные соединения, просто чтобы иметь возможность обрабатывать события при открытом соединении, получении сообщений и закрытии соединения.

[Редактировать]
Мысль о создании слова, в котором ключом является Sec-websocket-key, а значением является объект WSHandler ... мысли? Я не уверен, насколько надежный Sec-websocket-key должен быть уникальным.

Насколько я знаю, для каждого соединения будет создан один экземпляр WSHandler. Итак, WSHandlers - это в основном только интерфейсы подключения. Может быть, вы хотите добавить какой-нибудь механизм обработки сообщений поверх сети, например, такой какcode.google.com/p/pyscxml ? Vladimir

Ваш Ответ

4   ответа
0

проверив происхождение conexion. Итак, переопределение методаdef check_origin(self, origin) может помочь Например:

clients = {}

class WSHandler(tornado.websocket.WebSocketHandler):


    def check_origin(self, origin): 

        clients[origin] = self
        print(clients)
        return True
23

WSHandler:

class WSHandler(tornado.websocket.WebSocketHandler):
    clients = []

    def open(self):
        self.clients.append(self)
        print 'new connection'
        self.write_message("Hello World")

    def on_message(self, message):
        print 'message received %s' % message

    def on_close(self):
        self.clients.remove(self)
        print 'closed connection'

Если вы хотите идентифицировать соединения, например, пользователем, вероятно, вам придется отправить эту информацию через сокет.

@ColeMaclean отличный ответ! Но что если в системе с несколькими пользователями я хочу отправить данные, полученные от одного клиента websocket (browser1), который также обновил базу данных, и передать эти данные другому клиенту (browser2)?
@ direwolf7 Вы должны обрабатывать все это (или предпочтительно вызывать что-то еще, что делает) вon_message
Одним из способов (например) было бы отправить идентификатор сеанса через сокет, обработать его вon_messageи сохранить его наWSHandler экземпляр (или где угодно).
Понятно, спасибо чувак :))
If you want to identify connections, e.g. by user, you'll probably have to send that information over the socket., Я не понимаю, что вы имеете в виду здесь? Как определить соединение по пользователю?
1

он может быть добавлен к конечной точке вашего веб-сокета, скажем, и получен при инициализации сокета даже до его открытия (но, пожалуйста, работайте поверх SSL).

Если токен доступа недоступен, либо из-за того, что пользователь не предоставил один, либо из-за того, что предоставленный им токен истек, пользователь не аутентифицирован, и вы убьете сокет при первой же возможности.

Однако, если вы это сделаете, токен доступа должен быть связан с пользователем, у которого будет идентификатор, и этот идентификатор затем можно будет привязать к сокету даже до его открытия. Идентификатор может служить словарным ключом, значением которого является набор сокетов, привязанных к этому пользователю.

19

когда вам нужен только список всех соединений. Однако, если вы хотите что-то более сложное, это можно отслеживать за пределамиWSHandler пример - будь смелым, сделай это так:

class WSHandler(tornado.websocket.WebSocketHandler):

    def open(self):
        self.id = uuid.uuid4()
        external_storage[self.id] = {'id':self.id}
        print 'new connection'
        self.write_message("Hello World")

    def on_message(self, message):
        #Some message parsing here
        if message.type == 'set_group':
           external_storage[self.id]['group'] = message.group
        print 'message received %s' % message

    def on_close(self):
        external_storage.remove(self.id)
        print 'closed connection'
@Nikolay, действительно хороший ответ Николай, очень хорошая идея отслеживать пользователей, не позволяя им отправлять, кто они, вы можете легко идентифицировать их и отправить сообщение / соответственно закрыть соединение ... Хорошая работа :)). Обычно хранение такого рода информации осуществляется с помощью Redis.
Что если у меня есть несколько серверов торнадо? Как я могу общаться между ними и клиентами (браузерами)?
Ответ Коула делает то, что мне нужно, но я буду иметь в виду ваш, если мне нужно больше контроля за пределами самого WSHandler. Ценю помощь! Joseph
Могу ли я на самом деле сохранить объект-обработчик во внешнем кеше, как memcached? Я думаю, что сам объект может быть сериализован, однако он связан с соединением, я не уверен, будет ли он потерян или нет ...
Определенно надежный способ справиться с этим сценарием.

Похожие вопросы