Creating a CherryPy with ws4py socket heartbeat

1.1k Views Asked by At

I have spent about 5 hours searching for how to do this to no avail.

We are using ws4py on top of cherrypy. At current, when a connection is physically lost (say you turn off your WiFi) the connection will not be terminated untill a message is sent from the server, at which point it detects the dropped line and cleans up the socket.

This is causing us issues, and we need to know sooner if the socket is gone.

the file "websocket.py" in ws4py has a class called "Heartbeat" which looks like exactly what I want, and I believe that an instance is created inside the "WebSocket" if its has a "heartbeat_freq" parameter passed in;

class WebSocket(object):
""" Represents a websocket endpoint and provides a high level interface to drive the endpoint. """

    def __init__(self, sock, protocols=None, extensions=None, environ=None, heartbeat_freq=None):

Above is the ws4py ctor, but I cannot find where this code is called from. What I do know is that it is tied up in a CherryPy callback system. Here is what I found;

The above ctor is called from "cherrypyserver.py" in the function;

def upgrade(self, protocols=None, extensions=None, version=WS_VERSION, handler_cls=WebSocket, heartbeat_freq=None):

This function seems to be a callback, as it is called from _cprequest.py in a function

def __call__(self):
    """Run self.callback(**self.kwargs)."""
    return self.callback(**self.kwargs)

Now there is a bit more stuff floating around but in honesty I'm kinda lost, and think I am going about this wrong.

From what I can figure out, I need to set the "heartbeat_freq" parameter of the callback, but am not sure where I would set this parameter. The code below is where I specify the "WebSocket" handler class (websocket2.Handler inherits from "WebSocket") that the callback creates an instance of.

rootmap2={
    'wsgi.pipeline': [
        ('validator1', validator),
        ('validator2', validator),
        ]   ,   
        'tools.websocket.on': True,
        'tools.websocket.handler_cls': websocket2.Handler,

    }

I believe that somewhere in this "rootmap" I have to specify the parameter. Does anybody know how to do this.

To clarify, I want my server to create a heartbeat for each peer. I believe this is done by passing in a "heartbeat_freq" value.

At current I am just broadcasting a heartbeat to all, which I dont like the sound of personally

1

There are 1 best solutions below

0
On

The heartbeat is only activated when the websocket object has its run method executed (usually in a thread as it's blocking). However the CherryPy plugin does not use that code path anymore for various reasons. I'm not yet decided as to what to do with the heartbeat yet because, as it stands, it'd have to be run in its own thread for each websocket. I find that expensive memory-wise. However, if you do need that feature, create an instance of the Heartbeat class with the websocket instance. Simply hold a reference to each Heartbeat instance.