Search code examples
pythontornado

How to calculate to web latency in torando?


I'm using tornado web sockets and would like to calculate web socket latency to the client. I have seen using ping/pong in tornado but I didn't understand it clearly and there is no good example.

Is there any simple example code to send ping/pong response and calculate web response?


Solution

  • I have used this below code to calculate the WebSocket latency. Ping will send a timestamp. In pong, we receive the ping timestamp and calculate the latency by subtracting ping timestamp from the current time.

    class EchoWebSocket(tornado.websocket.WebSocketHandler):
    
        def open(self):
            ping_errors = 0
    
            # Send a ping packet with the timestamp
            def send_ping():
                global ping_errors
                timestamp = time.time()
                try:
                    self.ping(str(timestamp).encode('utf-8'))
                    ping_errors = 0
                except tornado.websocket.WebSocketClosedError:
                    msg = "Web socket closed. Stopped ping."
                    logger.info(msg)
                    pinger.stop()
                except Exception:
                    ping_errors += 1
                    msg = "Ping failed to send."
                    logger.error(msg, exc_info=True)
    
                    if ping_errors > 3:
                        msg = "Stopping ping."
                        logger.error(msg, exc_info=True)
                        pinger.stop()
    
            interval = 10000 #ms
            pinger = tornado.ioloop.PeriodicCallback(send_ping, interval)
            pinger.start()
    
        def on_pong(self, timestamp):
            curr_time = time.time()
            time_diff  = curr_time - float(timestamp)
    
            if time_diff < 0:
                logger.info("Lost a ping packet")
                return
            logger.info("WebSocket Latency: {0}ms".format(
                int(ceil(time_diff * 1000))))
    
        def on_close(self):
            print("WebSocket closed")
    

    In handlers,

    handlers = [
                 ...,
                 (r'/ping', EchoWebSocket),
               ]
    

    In javascript,

    protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
    ping_ws_url = protocol + window.location.host + "/ping";
    ping_ws = new WebSocket(ping_ws_url);