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

sio.disconnect() will connect after a connection drop #1277

Open
ghost opened this issue Nov 9, 2023 · 21 comments
Open

sio.disconnect() will connect after a connection drop #1277

ghost opened this issue Nov 9, 2023 · 21 comments
Assignees

Comments

@ghost
Copy link

ghost commented Nov 9, 2023

Describe the bug
sio.disconnect() will connect after a connection drop

To Reproduce
Steps to reproduce the behavior:

  1. Connect to your backend
  2. do the functions you want
  3. once done, use sio.disconnect() and it will reconnect if you dropped connections

Expected behavior
should fully disconnect, not connect again

Logs

Emitting event "send_position_1" [/]
Received event "get_position_1" [/]
Engine.IO connection dropped
Connection failed, new attempt in 1.43 seconds
Engine.IO connection established
Namespace / is connected
Reconnection successful

Additional context
once connection dropped, and then using sio.disconnect(), it will reconnect after

@ghost ghost changed the title sio.disconnect() connects after reconnecting sio.disconnect() will connect after a connection drop Nov 9, 2023
@miguelgrinberg
Copy link
Owner

This is likely a problem in your application. Could you please share a simple client and server that reproduce this problem?

@ghost
Copy link
Author

ghost commented Nov 9, 2023

I dont have a simple example of it, as its a pygame app

but here is some of the code with most stuff cut out that isnt socketio related

def multiplayer():
    global paddle_a, paddle_b, ball, ball_dx, ball_dy, score
    initialize_game()
    sio.connect('https://ultimatepingpongsocket.xytriza.com')
    while True:
        if ball.left <= 0:
            if sio.connected:
                sio.disconnect()
            initialize_game()
            death_screen(score, 2)
        if ball.right >= 800:
            if sio.connected:
                sio.disconnect()
            initialize_game()
            death_screen(score, 2)

        keys = pygame.key.get_pressed()
        if keys[pygame.K_w] and paddle_a.top > 0:
            paddle_a.y -= 5
            if sio.connected:
                sio.emit('send_position_2', paddle_a.y)
        if keys[pygame.K_s] and paddle_a.bottom < 600:
            paddle_a.y += 5
            if sio.connected:
                sio.emit('send_position_2', paddle_a.y)

        pygame.display.flip()
        pygame.time.Clock().tick(60)

for some reason if i send too many updates to the server itll cause a freeze

@miguelgrinberg
Copy link
Owner

The logs do not show that you have initiated a disconnection, they show that the client lost the connection to the server, and for that reason it is attempting to reconnect. If you do not want reconnections to happen, you can disable it when you create the client object.

@ghost
Copy link
Author

ghost commented Nov 10, 2023

well i lost connection a bit before i died, and then disconnect didnt do anything

@ghost
Copy link
Author

ghost commented Nov 10, 2023

i do want reconnects tho, just not after sio.disconnect()

@miguelgrinberg
Copy link
Owner

Let me see if I understand. You got disconnected from the server, and while the client was in the process of reconnecting you called disconnect()? And your expectation is that this will stop the reconnection?

@vipcxj
Copy link

vipcxj commented Nov 13, 2023

@miguelgrinberg Hi, How can I recognize whether the disconnect event is triggered by invoking disconnect method or a network issue in on callback? I think we should use another event (maybe called close) to represent disconnect triggered bt user manually disconnect. The socket.io official provide a reason as the argument of the callback, however according document, python-socketio use a none argument callback for disconnect event. I think the official approach is bizarre, but at least it offers a solution

@miguelgrinberg
Copy link
Owner

@vipcxj correct, the disconnect reason is not being exposed to the disconnect handler. I have never got around to expose that. Will think about how to best do this.

@ghost
Copy link
Author

ghost commented Nov 13, 2023

Let me see if I understand. You got disconnected from the server, and while the client was in the process of reconnecting you called disconnect()? And your expectation is that this will stop the reconnection?

yes this is correct, when dropping connection to the server, and then disconnect() it should cancel the reconnect, not continue it as its meant to be disconnected

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Nov 14, 2023

The thing is, calling disconnect when you are disconnected doesn't do anything, since you are already disconnected.

There is currently no way to interrupt a reconnect loop, but there are options to disable reconnects, or to indicate how many retries you want before giving up. I will consider adding a way to interrupt a reconnect loop in the future, but right now it is not possible.

@ghost
Copy link
Author

ghost commented Nov 15, 2023

it should cancel the reconnect.

@miguelgrinberg
Copy link
Owner

As I said, I will think about how to interrupt a reconnect loop.

@ghost
Copy link
Author

ghost commented Nov 18, 2023

ok👍

@blazing-gig
Copy link

I managed to achieve this by manually setting the _reconnect_abort event explicitly like so:

if self._sio_client.connected:
    await self._sio_client.disconnect()
    if self._sio_client._reconnect_abort:
        self._sio_client._reconnect_abort.set()

This seems to have worked.
@miguelgrinberg Could you pls comment on if this can serve as a potential workaround or even a fix ?

@ghost
Copy link
Author

ghost commented Jan 9, 2024 via email

@ghost
Copy link
Author

ghost commented Jan 9, 2024 via email

@blazing-gig
Copy link

blazing-gig commented Jan 9, 2024

@Xytriza You can get rid of the self if you aren't using classes. sio_client from my example above, is just an instance of socketio.AsyncClient.

@ghost
Copy link
Author

ghost commented Jan 9, 2024

ok

@miguelgrinberg
Copy link
Owner

I managed to achieve this by manually setting the _reconnect_abort event explicitly like so:

if self._sio_client.connected:
    await self._sio_client.disconnect()
    if self._sio_client._reconnect_abort:
        self._sio_client._reconnect_abort.set()

This seems to have worked. @miguelgrinberg Could you pls comment on if this can serve as a potential workaround or even a fix ?

This is not something that I would recommend, because you are using private attributes that are not guaranteed to be preserved in future releases, but as a temporary workaround it may be okay. You should probably wait for the reconnect task to end after signaling it to exit.

@blazing-gig
Copy link

@miguelgrinberg Right. So I believe just adding this line should do:

if self._sio_client.connected:
    await self._sio_client.disconnect()
    if self._sio_client._reconnect_abort:
        self._sio_client._reconnect_abort.set()
        await self._sio_client._reconnect_task # Per your suggestion

@miguelgrinberg
Copy link
Owner

Sure. As I said above though, I cannot guarantee that this will continue to work in future versions, since you are accessing privates/internals of the library.

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

No branches or pull requests

3 participants