Search code examples
pythonmultithreadingwebsockettornado

WebSocket Threading using Global Variables


I'm trying to create a WebSocket server using the very popular Tornado server for Python, but I'm having an issue creating a global-scoped self variable in order to write data to the web socket outside the class.

This answer solved my problem exactly, but I wanted to take it a step further and wrap the whole thing in a thread.

This is my socket:

wss = []

class WSHandler(tornado.websocket.WebSocketHandler):

    def check_origin(self, origin):
        return True

    def open(self):
        print ('New connection established.')
        if self not in wss:
            wss.append(self)

    def on_message(self, message):
        print ('Received message: %s' % message)

    def on_close(self):
        print ('Connection closed.')
        if self in wss:
            wss.remove(self)

This is the method that is outside of the class that writes to the socket:

def write_data(message):
    for ws in wss:
        print ("Sending: %s" % message)
        ws.write_message(message);

This is the threaded server class:

class ServerThread(threading.Thread):

    def run(self):
        print ("Starting server.")
        http_server = tornado.httpserver.HTTPServer(application)
        http_server.listen(4045)
        main_loop = tornado.ioloop.IOLoop.instance()
        main_loop.start()

    def send_data(self, message):
        write_data(message);

The strange thing is, when the code is not wrapped in a Thread class, the write method works fine. In the code above, when I call:

server_thread = ServerThread()
server_thread.start()
server_thread.send_data("Ping!")

nothing happens. The method write_data(message) is entered, but evidently wss[] is empty.

Any help you could provide would be greatly appreciated!

Update:

I've been continuously looking into this problem to no avail. Another strange thing: New connection established. never prints to the console making me think that the socket is never appended to the list rather than it being a variable scoping problem.


Solution

  • You are not supposed to use port 4045 for HTTP/WebSocket service, as it's blocked by browser. You may get an error message from browser:

    Failed to construct 'WebSocket': The port 4045 is not allowed.
    

    http://www-archive.mozilla.org/projects/netlib/PortBanning.html http://support.apple.com/en-us/HT203772