Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling disconnect() will not disconnect the client. #167

Open
roniemartinez opened this issue Sep 23, 2017 · 3 comments
Open

Calling disconnect() will not disconnect the client. #167

roniemartinez opened this issue Sep 23, 2017 · 3 comments

Comments

@roniemartinez
Copy link

roniemartinez commented Sep 23, 2017

Hi,

I started the client using "wait forever" as described on the README. When calling disconnect(), the session gets disconnected, however, the engineio will still be running and tries to reconnect with a new session.

What is not clear is that it wasn't described in the documentation/code if disconnect() is actually for the sessions or for the client.

As for my use case, I patched

def _get_engineIO_session(self):
and added

if self._should_stop_waiting():
    break

The code should look like this.

 def _get_engineIO_session(self):
        warning_screen = self._yield_warning_screen()
        for elapsed_time in warning_screen:
            # added condition
            if self._should_stop_waiting():
                break
            transport = XHR_PollingTransport(
                self._http_session, self._is_secure, self._url)
            try:
                engineIO_packet_type, engineIO_packet_data = next(
                    transport.recv_packet())
                break
            except (TimeoutError, ConnectionError) as e:
                if not self._wait_for_connection:
                    raise
                warning = Exception(
                    '[engine.io waiting for connection] %s' % e)
                warning_screen.throw(warning)
        assert engineIO_packet_type == 0  # engineIO_packet_type == open
        return parse_engineIO_session(engineIO_packet_data)

I just want to make it clear if the disconnect() function is only for sessions, if yes, please expose a function for "client disconnection".

Thanks!

@jlustk
Copy link

jlustk commented Dec 22, 2017

Unfortunately this does not work for me. Maybe there are more ideas, how can I break the connection?

@ranjanagwl
Copy link

@Code-ReaQtor @jlustk
I was facing the same issue where I wanted socket client disconnect instead of session disconnect.
Basically even after calling socket.disconnect(), Connection would still be open and active.

Hence, for complete client disconnect I made two changes:

  1. Close the underlying connection as suggested in PR Closing connections on EngineIO._close() #126. It is mandatory because underlying socket connection and http session is never closed.
  2. Stop the connection from being established again (i.e. stop generation of new Transport instance).

Reason for doing step 2 is there is kind of deadlock situation that always invokes a new Transport instance irrespective on invoking disconnect.
What happens is as follows...

  • After invoking socket.disconnect(), self._close() is invoked
  • In self._close, self._wants_to_close and self._opened is marked as false
  • Now there are two threads running in background, heartbeat thread and wait thread (for events). In self._close heartbeat thread is stopped.
  • Upon setting self._wants_to_close as false, wait thread is terminated.
  • However just after wait loop is over it invokes a function self._transport.set_timeout() (socketIO-client/socketIO_client/init.py Line 270)
  • As we can see self._transport is defined as: socketIO-client/socketIO_client/init.py Line 58
    @property
    def _transport(self):
        if self._opened:
            return self._transport_instance
        self._engineIO_session = self._get_engineIO_session()
        self._negotiate_transport()
        self._connect_namespaces()
        self._opened = True
        self._reset_heartbeat()
        return self._transport_instance
  • Since, self._opened is marked as false, new transport instance is generated (i.e. new connection altogether) upon invoking self._transport.set_timeout()
  • Hence, to prevent the above chain of events from happening, I modified socketIO-client/socketIO_client/init.py Line 60 as follow
        if self._opened and self._wants_to_close:
            return self._transport_instance
  • With this patch, new connection will not open if self._wants_to_close is marked as True.

Hope this helps!

This may also be related to following issues:

@harmon
Copy link

harmon commented Dec 18, 2018

Shouldn't that be if self._opened or self._wants_to_close: ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants