Как переподключиться к веб-сокету, когда я обновляю веб-страницу клиента - PullRequest
0 голосов
/ 24 мая 2019

Когда я обновляю свою клиентскую веб-страницу, я прекращаю получать данные от сервера сокета торнадо.Как я могу повторно подключиться к потоку?

Я пытался добавить объекты соединения в список, а затем удалить соединение из списка, когда оно закрывается, но оказывается, что когда вы обновляете страницу, соединение никогда не закрывается, он остается активным в соответствии с сервером, но он также больше не получает данные на стороне клиента: (

Это мой сервер торнадо

# python 3
from tornado import web, httpserver, ioloop, websocket, options
from time import time, sleep


class ChannelHandler(websocket.WebSocketHandler):
    """Handler that handles a websocket channel"""
    connections = list()

    @classmethod
    def urls(cls):
        return [(r'/websocket', cls, {})]

    def initialize(self):
        self.channel = None

    def open(self):
        # When Client opens a websocket
        # add the new connnection to connections
        self.connections.append(self)

    def on_message(self, message):
        # Message received on channel
        # keep sending all connected clients the time info
        while True:
            [client.write_message({'time()': str(time())}) for client in self.connections]
            sleep(1)
            print('still sending')

    def on_close(self):
        # Channel is closed
        # delete client from active connections if they close connection
        self.connections.remove(self)
        print('CLOSED connection?')

    def check_origin(self, origin):
        # Override the origin check if needed
        return True


def main():
    # Create tornado application and supply URL routes
    app = web.Application(ChannelHandler.urls())
    # Setup HTTP Server
    http_server = httpserver.HTTPServer(app)
    http_server.listen(8000, 'localhost')
    # Start IO/Event loop
    ioloop.IOLoop.instance().start()


if __name__ == '__main__':
    main()

И клиент сокетов

<script type="text/javascript">
    var ws = new WebSocket("ws://localhost:8000/websocket");
    ws.onopen = function () {
        ws.send("Hello, world");
    };
    ws.onmessage = function (evt) {
        console.log(evt.data);
    };
</script>

Итак, как мне продолжать получать данные с сокет-сервера, когда я обновляю свою веб-страницу о чистоте?

1 Ответ

1 голос
/ 24 мая 2019

Цикл while блокирует весь ваш сервер. Вы добавили вызов sleep(1) в цикл, чтобы приостановить цикл на секунду, но time.sleep - это блокирующая функция, поэтому она также не помогает.

Вам нужно использовать асинхронную альтернативу time.sleep - Tornado's gen.sleep.

Вам также необходимо преобразовать функцию on_message в сопрограмму.

Пример:

from tornado import gen


async def on_message(...):
    ...
    while True:
        ...
        await gen.sleep(1)
        ...

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

В этом случае вам также необходимо немного изменить свой код. set не имеет метода append, вместо этого он имеет метод add.

connections = set()
...
self.connections.add(self) # to add connection
...
self.connections.remove(self) # to remove connetion
...