socketIO-client icon indicating copy to clipboard operation
socketIO-client copied to clipboard

Automatic Reconnect

Open randellhodges opened this issue 8 years ago • 4 comments

Is there a way for the client to detect a network loss and reconnect?

I tried .wait() then I tried with a .wait(seconds=15) and then look at the .connected probably and it is always true. I would get the app up and running and then pull the network cable for about a minute. The connected property always said true and even after plugging it back in, nothing happened. It was pretty much dead.

Am I doing something wrong? Any examples with auto reconnect? I see that it is suppose to send a ping on another thread. Maybe that isn't bubbling back up to me? Should that cause the wait method to unblock and exit or at least throw while I'm "wait"ing?

This was with v0.6.5

randellhodges avatar Dec 08 '16 13:12 randellhodges

same issue @randellhodges did you find any answer?

DaniyalGeek avatar Dec 10 '16 16:12 DaniyalGeek

Have you tried the latest release? https://pypi.python.org/pypi/socketIO-client/0.7.2

Auto reconnect should work. I don't remember having issues with it.

from socketIO_client import SocketIO, BaseNamespace

class Namespace(BaseNamespace):

    def on_connect(self):
        print('[Connected]')

    def on_reconnect(self):
        print('[Reconnected]')

    def on_disconnect(self):
        print('[Disconnected]')

socketIO = SocketIO('localhost', 8000, Namespace)
socketIO.wait(seconds=30)

You might want to try a variation of the code snippet above to see what is happening.

invisibleroads avatar Dec 11 '16 03:12 invisibleroads

First disclaimer: I am extremely new to python.

I was on 0.6.5. The latest versions didn't work for me. I think it was due to a dependency issue. I did a variation of the above, and it would reconnect. I was basically timing the pings and if I missed a ping, I would reconnect.

It is probably not how I should do it, and I am new to python.

I capture the current time in _on_socket_pong and I also get the ping timeout from socketIO in the connect. When wait stops blocking, I look to see if we missed a scheduled pong, and if so, I let the loop exit and it reconnects. I run this in it's own thread.

I know it breaks a few rules regarding encapsulation and the disclaimer is, it works for me, on the server I was hitting and for the version I was using.

    def _on_socket_connect(self, socket):
    
        # We will try to see what our ping check should be. It does use _variables, so
        # we'll have a fallback value
        try:
            interval = socket._engineIO_session.ping_interval
            if timeout > 0:
                self.ping_interval = interval
        except:
            pass
            
        try:
            timeout = socket._engineIO_session.ping_timeout
            if timeout > 0:
                self.ping_timeout = timeout
        except:
            pass
            
        self.last_pong = time.time()
        
    def _on_socket_pong(self, data):
        self.last_pong = time.time()
        
    def _on_socket_response(self, *args):
        self.last_pong = time.time()
   
     def _run(self):
    
        while not self.stopped.isSet():
        
            try:
                with self.SocketIO(STREAM_URL, params=self.params) as socket:
                
                    socket.on('connect', lambda: self._on_socket_connect(socket))
                    socket.on('pong', self._on_socket_pong)

                    # Note: ping_timeout and ping_interval may adjust after the initial connection
                    while not self.stopped.isSet():
                        
                        # We need to wait for at least our ping interval, otherwise the wait will
                        # trigger a ping itself.
                        socket.wait(seconds=self.ping_timeout)
                        
                        # Check that we have gotten pongs or data sometime in
                        # the last XX seconds. If not, we are going to assume we need
                        # to reconnect
                        now = time.time()
                        diff = int(now - (self.last_pong or now))
                        
                        if diff > self.ping_interval:
                            break
                
            except (TimeoutError, ConnectionError, ConnectionResetError):
                # We are going to ignore these and go back thru the loop
                time.sleep(5)

randellhodges avatar Dec 13 '16 16:12 randellhodges

@invisibleroads do you have time for this issue?

khanhvu161188 avatar Jan 05 '17 01:01 khanhvu161188