Click here to Skip to main content
15,895,667 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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:
Python
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 ...")


client being :
Python
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()


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
Posted
Comments
Richard MacCutchan 4-Mar-19 6:16am    
If you got this code from a StackOverflow answer, then that is the best place to post your question.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900