For testing a WebSocket client, I am writing a small tornado WebSocket server, which resides in a designated thread and can be started and stopped during test runtime. Here is what I have come up with so far:
class SocketHandler(tornado.websocket.WebSocketHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
self.authenticated = False
def check_origin(self, origin):
return True
def open(self):
pass
def on_message(self, message):
pass
def on_close(self):
pass
application = tornado.web.Application([
(r"/ws", SocketHandler),
])
class WebSocketServer(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self, name='WebServer')
self.port = port
self.ioloop = None
def run(self):
self.ioloop = tornado.ioloop.IOLoop()
http_server_api = tornado.httpserver.HTTPServer(application)
http_server_api.listen(self.port)
self.ioloop.start()
http_server_api.stop()
self.ioloop.clear_instance()
def stop(self):
self.ioloop.add_callback(self.ioloop.stop)
Starting the server works well:
server = WebSocketServer(8888)
server.start()
I can conncet to the server using any WebSocket client. Unfortunately, when I stop the server:
server.stop()
the thread closes, the listen port of the server is being removed, but all established WebSocket connections remain intact. How can I close all established connections as well? Thanks for the help!
In Tornado 5.1 there's no easy way to do this for websocket connections (for regular HTTP there's HTTPServer.close_all_connections). You'll just have to keep track of all your connections and explicitly close them. Tornado's own test suite jumps through a lot of ugly hoops to make this work without spamming the logs with warnings about unclean shutdown.
In Tornado 6.0 I want to fix this so that HTTPServer.close_all_connections is aware of websocket connections and closes them too.