Ilker Kesen
Ilker Kesen

Reputation: 513

tornado - WebSocketClientConnection - How to catch and handle connection failures?

I am a Tornado and also Websocket newbie. There are many resources how to implement a websocket server application with Tornado. However, I haven't found a complete example that contains a websocket client application built on top of Tornado.


Server Application (server.py)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import logging
import tornado.web
import tornado.websocket
import tornado.ioloop
import tornado.options

from tornado.options import define, options

define("port", default=3000, help="run on the given port", type=int)


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [(r"/", MainHandler)]
        settings = dict(debug=True)
        tornado.web.Application.__init__(self, handlers, **settings)


class MainHandler(tornado.websocket.WebSocketHandler):
    def check_origin(self, origin):
        return True

    def open(self):
        logging.info("A client connected.")

    def on_close(self):
        logging.info("A device disconnected")


def main():
    tornado.options.parse_command_line()
    app = Application()
    app.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()


if __name__ == "__main__":
    main()

Client Application (client.py):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from tornado.ioloop import IOLoop
from tornado.websocket import websocket_connect


if __name__ == "__main__":
    ws = websocket_connect("ws://localhost:3000")
    IOLoop.instance().start()

Problems & Questions

I don't have any problems with server application. However, I can't say same thing for client application. Why?

  1. If server goes down, client application doesn't react. It does not say "Hey, server is down buddy.". I write my own WebSocketClientConnection class (inherited by the original) and also websocket_connect function (same function, but this one uses my WebSocketClientConnection class). I override on_connection_close method in my WebSocketClientConnection class, so I can catch "server down on middle of the connection" failure. However, I cannot make it reconnect. How do I make it reconnect to server?
  2. If server is already down before the connection, client application does not raise anything and seems perfectly. I don't know how to catch that failure. How do I catch this connection failure?

My WebSocketClientConnection class:

class MyWebSocketClientConnection(tornado.websocket.WebSocketClientConnection):
    def on_connection_close(self):
        super(MyWebSocketClientConnection, self).on_connection_close()
        print "connection closed"

Thanks.

Upvotes: 1

Views: 3823

Answers (2)

Ilker Kesen
Ilker Kesen

Reputation: 513

By the way, after I figured out, I did write an example Tornado WebSocket client/server pair to demonstrate how to do it.

https://github.com/ilkerkesen/tornado-websocket-client-example

I hope it helps someone.

Upvotes: 3

Ben Darnell
Ben Darnell

Reputation: 22154

websocket_connect returns a Future; to see whether it succeeded or failed you must examine the Future (probably by yielding it in a coroutine). Furthermore, after establishing the connection you should go into a read_message loop. Even if you don't expect the client to send any messages, you should still call read_message: this is how you will connections that are closed after being established (read_message will return None).

@gen.coroutine
def my_websocket_client(url):
    ws = yield websocket_connect(url)
    while True:
        msg = yield ws.read_message()
        if msg is None: break
        # do stuff with msg

Upvotes: 1

Related Questions