Неблокирующие запросы Tornado WebSockets с использованием потоков.Я делаю это правильно? - PullRequest
0 голосов
/ 01 июня 2018

Я новичок в Python, и проблема, которую я пытаюсь решить, заключается в том, чтобы иметь постоянное соединение с веб-сокетом, которое может принимать запросы, подождать некоторое время при выполнении вызовов, вернуть результаты, когда будет готово, не блокируя другие поступающие запросы.от других пользователей / клиентов / подключений.Я добился этого, и он работает довольно хорошо, но хотел проверить, является ли это правильным решением.В этом конкретном фрагменте ключевой бит - это действия, выполняемые при открытии: я раскручиваю другой поток со сном.

import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import time
import json
from tornado import gen
from concurrent.futures import ThreadPoolExecutor
from tornado.options import define, options, parse_command_line

define("port", default=8888, type=int)

thread_pool = ThreadPoolExecutor(2)

class WebSocketHandler(tornado.websocket.WebSocketHandler):
    # Make this an asynchronous coroutine
    @gen.coroutine
    def on_message_coroutine(self, message):
        self.write_message('Message:', message)

        def worker_A(websocket, x):
            time.sleep(1)
            print('TICK', x)
            pass
            return x

        print('scheduling and yielding')
        for x in range(0, 30):
            test = yield thread_pool.submit(worker_A, self, x)
            self.write_message(json.dumps(test))

        print('done yielding')

    def open(self, *args):
        print("New connection")
        tornado.ioloop.IOLoop.current().spawn_callback(self.on_message_coroutine, 'New Msg')

    def check_origin(self, origin):
        return True

    def on_message(self, message):
        print("New message {}".format(message))
        self.write_message("You sent me this, sending it back in upper: " + message.upper())

    def on_close(self):
            print("Connection closed")

app = tornado.web.Application([
    (r'/ws/', WebSocketHandler),
])

if __name__ == '__main__':
    app.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

Вывод на консоли внешнего интерфейса ниже.Бит «Новое сообщение» - это когда я нажимаю кнопки, когда веб-сокет непрерывно возвращает другой вывод (TICKS):

app.component.ts:17 Response from websocket: 11
app.component.ts:17 Response from websocket: 12
app.component.ts:17 Response from websocket: 13
app.component.ts:17 Response from websocket: 14
app.component.ts:24 new message from client to websocket:  gotta be a string
app.component.ts:17 Response from websocket: You sent me this, sending it back in upper: "GOTTA BE A STRING"
app.component.ts:17 Response from websocket: 15
app.component.ts:17 Response from websocket: 16
app.component.ts:17 Response from websocket: 17
app.component.ts:24 new message from client to websocket:  gotta be a string
app.component.ts:17 Response from websocket: You sent me this, sending it back in upper: "GOTTA BE A STRING"
app.component.ts:17 Response from websocket: 18
app.component.ts:17 Response from websocket: 19
app.component.ts:17 Response from websocket: 20
app.component.ts:17 Response from websocket: 21

1 Ответ

0 голосов
/ 01 июня 2018

Да, это выглядит хорошо для меня.Главное, что нужно помнить, это то, что в worker_A (функция, которую вы передаете в executor.submit(), вы не должны вызывать write_message. Вместо этого возвращайте значение и пишите его после того, как yield executor.submit() вернул.

...