Рассылка сообщений клиентам торнадо
Следуя предложениям в:
https://stackoverflow.com/questions/26223951/how-can-i-send-message-to-clients-every-x-seconds-when-running-a-tornado-server
Сервера:
import tornado.httpserver import tornado.websocket import tornado.ioloop import tornado.web import socket import random import threading import time clients = [] def updateClients(): while True: for c in clients: c.write_message('your update data') time.sleep(0.500) #in milli-seconds you can use float point class WSHandler(tornado.websocket.WebSocketHandler): def open(self): print ('new connection') clients.append(self) def on_message(self, message): self.write_message('echo ' + message) def on_close(self): clients.remove(self) def check_origin(self, origin): return True def path(self): return request.path application = tornado.web.Application([ (r'/ws', WSHandler), ]) if __name__ == "__main__": t = threading.Thread(target = updateClients) t.start() #start the thread before tornado http_server = tornado.httpserver.HTTPServer(application) my_port = 8888 http_server.listen(my_port) # get the uri? # https://stackoverflow.com/questions/25837733/get-server-url-and-port-from-tornado-web-framework myIP = socket.gethostbyname(socket.gethostname()) # myPath = WSHandler.path() print ('*** Websocket Server Started IP=%s, Port:%d ***' % (myIP, port)) try: tornado.ioloop.IOLoop.instance().start() except KeyboardInterrupt: http_server.close() print("Closing ...")
клиент :
from tornado import escape from tornado import gen from tornado import httpclient from tornado import httputil from tornado import ioloop from tornado import websocket import functools import json import time APPLICATION_JSON = 'application/json' DEFAULT_CONNECT_TIMEOUT = 60 DEFAULT_REQUEST_TIMEOUT = 60 class WebSocketClient(): """Base for web socket clients. """ def __init__(self, *, connect_timeout=DEFAULT_CONNECT_TIMEOUT, request_timeout=DEFAULT_REQUEST_TIMEOUT): self.connect_timeout = connect_timeout self.request_timeout = request_timeout def connect(self, url): """Connect to the server. :param str url: server URL. """ headers = httputil.HTTPHeaders({'Content-Type': APPLICATION_JSON}) request = httpclient.HTTPRequest(url=url, connect_timeout=self.connect_timeout, request_timeout=self.request_timeout, headers=headers) ws_conn = websocket.WebSocketClientConnection(ioloop.IOLoop.current(), request) ws_conn.connect_future.add_done_callback(self._connect_callback) def send(self, data): """Send message to the server :param str data: message. """ if not self._ws_connection: raise RuntimeError('Web socket connection is closed.') self._ws_connection.write_message(escape.utf8(json.dumps(data))) def close(self): """Close connection. """ if not self._ws_connection: raise RuntimeError('Web socket connection is already closed.') self._ws_connection.close() def _connect_callback(self, future): if future.exception() is None: self._ws_connection = future.result() self._on_connection_success() self._read_messages() else: self._on_connection_error(future.exception()) @gen.coroutine def _read_messages(self): while True: msg = yield self._ws_connection.read_message() if msg is None: self._on_connection_close() break self._on_message(msg) def _on_message(self, msg): """This is called when new message is available from the server. :param str msg: server message. """ pass def _on_connection_success(self): """This is called on successful connection ot the server. """ pass def _on_connection_close(self): """This is called when server closed the connection. """ pass def _on_connection_error(self, exception): """This is called in case if connection to the server could not established. """ pass class TestWebSocketClient(WebSocketClient): def _on_message(self, msg): print(msg) deadline = time.time() + 1 ioloop.IOLoop().instance().add_timeout( deadline, functools.partial(self.send, str(int(time.time())))) def _on_connection_success(self): print('Connected!') self.send(str(int(time.time()))) def _on_connection_close(self): print('Connection closed!') def _on_connection_error(self, exception): print('Connection error: %s', exception) def main(): client = TestWebSocketClient() client.connect('ws://localhost:8888') try: ioloop.IOLoop.instance().start() except KeyboardInterrupt: client.close() if __name__ == '__main__': main()
Когда соединение установлено я получаю ошибку клиента:
Обратная трассировка (самый недавний призыв последнего):
Файл "SimpleTornadoClient.py", строка 139, in <module>
главный()
Файл "SimpleTornadoClient.py", строка 130, в основном
client.connect('ws://localhost:8888')
Файл "SimpleTornadoClient.py", линия 43, in connect
запрос)
Файл "C:\Python37\lib\site-packages\tornado\websocket.py", строка 1381, in __init__
scheme, sep, rest = request.url.partition(":")
AttributeError: объект 'AsyncIOMainLoop' не имеет атрибута 'url'
Есть идеи, почему?
Что я уже пробовал:
Клиенты "торнадо" не удалось подключиться
Richard MacCutchan
Если вы получили этот код из ответа StackOverflow, то это лучшее место для публикации вашего вопроса.