Following the suggestions in:
https://stackoverflow.com/questions/26223951/how-can-i-send-message-to-clients-every-x-seconds-when-running-a-tornado-server
Server being:
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)
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()
http_server = tornado.httpserver.HTTPServer(application)
my_port = 8888
http_server.listen(my_port)
myIP = socket.gethostbyname(socket.gethostname())
print ('*** Websocket Server Started IP=%s, Port:%d ***' % (myIP, port))
try:
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
http_server.close()
print("Closing ...")
client being :
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()
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)
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)
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)
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)
pass
def _on_connection_success(self)
pass
def _on_connection_close(self)
pass
def _on_connection_error(self, exception)
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()
When connection is made I am getting client error:
Traceback (most recent call last):
File "SimpleTornadoClient.py", line 139, in <module>
main()
File "SimpleTornadoClient.py", line 130, in main
client.connect('ws://localhost:8888')
File "SimpleTornadoClient.py", line 43, in connect
request)
File "C:\Python37\lib\site-packages\tornado\websocket.py", line 1381, in __init__
scheme, sep, rest = request.url.partition(":")
AttributeError: 'AsyncIOMainLoop' object has no attribute 'url'
Any idea why?
What I have tried:
Tornado clients unable to connect