Tornado Websocket сообщения не получают

1

У меня очень простая настройка, вдохновленная этим вопросом: Tornado - Слушайте несколько клиентов одновременно над веб-сайтами

По сути, у меня есть один обработчик Websocket, который может подключаться ко многим клиентам websocket. Затем у меня есть другой обработчик websocket "DataHandler", который будет транслировать сообщение каждый раз, когда он получает сообщение.

Поэтому я сделал глобальный список экземпляров TestHandler и использовал его для трансляции сообщений во все экземпляры

ws_clients = []

class TestHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print('open test!')
        ws_clients.append(self)
        self.random_number = random.randint(0, 101)

    def on_message(self, message):
        print(message)

        print('received', message, self, self.random_number)
        self.write_message('Message received')

    def on_close(self):
        print('closed')


class DataHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print('data open!')

    def on_message(self, message):
        for c in ws_clients:
            c.write_message('hello!')


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/test_service/", TestHandler),
            (r"/data/", DataHandler),
            (r"/", httpHandler)
        ]

        tornado.web.Application.__init__(self, handlers)


ws_app = Application()
ws_app.listen(8000)
tornado.ioloop.IOLoop.instance().start()

TestHandler может получать сообщения через адрес ws://127.0.0.1/test_service/ и DataHandler может получать сообщения в порядке через адрес ws://127.0.0.1/data/ но всякий раз, когда я ws_clients через ws_clients, я никогда не получаю никаких сообщений на TestHandler.

Я делаю что-то неправильно?

Теги:
websocket
tornado

1 ответ

2
Лучший ответ

Вот что я сделал бы - я бы создал новый метод TestHandler который будет служить одной цели - взять сообщение и отправить его всем подключенным клиентам.

Прежде чем перейти к коду, я хотел бы указать, что кажется (обычно) лучше поддерживать ws_clients внутри класса вместо глобального объекта. И используйте set вместо list.

class TestHandler(...):
    ws_clients = set() # use set instead of list to avoid duplicate connections

    def open(self):
        self.ws_clients.add(self)

    @classmethod
    def broadcast(cls, message):
        """Takes a message and sends to all connected clients"""
        for client in cls.ws_clients:
            # here you can calculate 'var' depending on each client
            client.write_message(message)

    def on_close(self):
        # remove the client from 'ws_clients'
        self.ws_client.remove(self)


# then you can call TestHandler.broadcast
# from anywhere in your code
# example:

class DataHandler(...):
    ...

    def on_message(self, message):
        # pass the message to TestHandler
        # to send out to connected clients
        TestHandler.broadcast(message)
  • 0
    Спасибо друг, ты гений

Ещё вопросы

Сообщество Overcoder
Наверх
Меню