laravel / echo

Laravel Echo library for beautiful Pusher and Ably integration.
https://laravel.com/docs/broadcasting#client-side-installation
MIT License
1.17k stars 179 forks source link

Socket.IO v3 refuses to reconnect after server fails and gets up again #295

Closed rennokki closed 3 years ago

rennokki commented 3 years ago

Description:

Running on Socket.IO v3, if the server drops connection while the client still tries to reconnect, Echo does not reconnect to the previously connected channels.

I am aware there is PR https://github.com/laravel/echo/issues/290 that aims at Socket.IO v3, but I watched for v2 features that changed in v3 that this package uses, and found none: https://socket.io/docs/v3/migrating-from-2-x-to-3-0

Steps To Reproduce:

  1. Run a Socket.IO v3 server (i have a modified fork here: echo-server)
  2. You will see something like this, in the Requests tab under WS, on connect: conn1
  3. Close the server. The client will now try to reconnect at the given interval.
  4. Reopen the server, watch for the client to reconnect. Once it reconnects, it should look like this: conn2
  5. You can clearly see that it did not reconnect to the private-team.1 channel on reconnection.

The private channel code is:

window.Echo.private('team.1') // for example
    .listen('.alert.updated', e => {
        //
    });
driesvints commented 3 years ago

It seems this is an issue in echo server itself: https://github.com/tlaverdure/laravel-echo-server/issues/547

rennokki commented 3 years ago

Actually, the issue is not regarding the "Bad handshake", somehow Echo refuses to re-subscribe on reconnection, especially listening to this event: https://github.com/laravel/echo/blob/v1.10.0/src/connector/socketio-connector.ts#L26-L30

driesvints commented 3 years ago

Hmm, I'll re-open this but will try to look into this when I have time for it. Appreciating any help however.

rennokki commented 3 years ago

It seems like the following bit of code added in socketio-connector.ts under on('reconnect', ...) handler seems to unsubscribe the user from all channels upon reconnection:

this.socket.on('disconnect', (reason) => {
    Object.values(this.channels).forEach((channel) => {
        channel.unsubscribe();
    });
});

Somehow, something queues the unsubscribes for the reconnection. Also, the on('reconnect', ...) is not read by any means.

driesvints commented 3 years ago

@rennokki hmm that's odd. Appreciating you looking into this. I'm not too familiar with this part here so I also don't know where the queueing would come from.

driesvints commented 3 years ago

We've decided we won't be investing time anymore into Socket.io since we don't maintain the laravel-echo-server package. Instead we recommend to use something like https://github.com/beyondcode/laravel-websockets. Sorry for this and thank you for understanding.