centrifugal / centrifugo

Scalable real-time messaging server in a language-agnostic way. Self-hosted alternative to Pubnub, Pusher, Ably. Set up once and forever.
https://centrifugal.dev
Apache License 2.0
8.44k stars 598 forks source link

[bug] getting "already subscribed" on page refresh #772

Closed xfourat closed 9 months ago

xfourat commented 9 months ago

Describe the bug. A clear and concise description of what the bug is.

I have a centrifuge-js client connecting just fine on first subscription everything goes fine and I can push some messages to the client, if the page is refereshed there will be no possible way to re-subscribe (even with a different jwt token on same channel).

Versions

Centrifugo version is 5.2.2 Client library used is centrifuge-js of version 5.0.1 Operating system is docker container

Steps to Reproduce How can the bug be triggered?

I have a centrifuge-js client connecting just fine on first subscription everything goes fine and I can push some messages to the client.

The issue begins when I referesh the page:

  1. {"level":"debug","client":"bed9ab98-28c9-4f1c-be88-8af7ade2f5d6","duration":126020.533783,"transport":"websocket","time":"2024-02-08T20:41:03Z","message":"client connection completed"}
  2. {"level":"debug","channel":"ns:channel_id","client":"bed9ab98-28c9-4f1c-be88-8af7ade2f5d6","user":"99900100","time":"2024-02-08T20:41:03Z","message":"client unsubscribed from channel"}
  3. {"level":"debug","method":"GET","status":101,"path":"/connection/websocket","addr":"192.168.65.1:50719","duration":"4.977871ms","time":"2024-02-08T20:41:12Z","message":"http request"} pgw-centrifugo | {"level":"debug","client":"634330b9-2c86-4999-be26-5ef25f2f5f4c","transport":"websocket","time":"2024-02-08T20:41:12Z","message":"client connection established"}
  4. {"level":"debug","client":"634330b9-2c86-4999-be26-5ef25f2f5f4c","user":"99900100.1","time":"2024-02-08T20:41:13Z","message":"client authenticated"} pgw-centrifugo | {"level":"debug","channel":"ns:channel_id","client":"634330b9-2c86-4999-be26-5ef25f2f5f4c","user":"99900100","time":"2024-02-08T20:41:13Z","message":"client subscribed to channel"}
  5. {"level":"info","channel":"ns:channel_id","client":"634330b9-2c86-4999-be26-5ef25f2f5f4c","user":"99900100","time":"2024-02-08T20:41:13Z","message":"client already subscribed on channel"}
  6. {"level":"info","client":"634330b9-2c86-4999-be26-5ef25f2f5f4c","code":105,"command":"id:2 subscribe:{channel:\"ns:channel_id\" token:\"eyJhbG**CI6IkpXVCJ95OTkwMDE**5lbHMiOlsi**LTI0MDM\"}","error":"already subscribed","reply":"id:2 error:{code:105 message:\"already subscribed\"}","user":"99900100","time":"2024-02-08T20:41:13Z","message":"client command error"}

Expected behavior What output or behaviour were you expecting instead?

I'm expecting the client to reconnect and resubscribe with no issue.

Code Snippets A minimum viable code snippet can be useful.

        const token = '{{ centrifuge_token }}';
        const centrifuge = new Centrifuge("ws://localhost:7999/connection/websocket", {token: token});
        const sub = centrifuge.newSubscription("ns:channel_id", {token: token});

        sub.on('publication', function (ctx) {
          console.log("received something:", ctx);
        }).subscribe();

fyi I'm generating jwt this way:

            centrifuge_token = jwt.encode({
                "sub": "99900100",
                "channels": ["ns:channel_id"],
                "expire_at": int(time.time())+3600},
                "******",
                algorithm="HS256")
FZambia commented 9 months ago

Hello @xfourat , this happens since you are subscribing to the same channel ns:channel_id using server-side subscription (by setting channels in token) and using client-side subscription (centrifuge.newSubscription("ns:channel_id", {token: token});).

Think you misunderstood what channels in connection token mean. Probably you decided that it's allowed channel to subscribe (permissions) – but it's not. When you have channels in token Centrifugo subscribes client to these channels automatically at the moment of connection establishment. So client-side subscription then receives already subscribed - because one client can't subscribes to the same channel twice.

xfourat commented 9 months ago

Thank you @FZambia

If centrifugo subscribes client to these channels automatically at the moment of connection establishment then how can have the sub object client side to use it for receiving messages ?

I have tried the followings without success:

FZambia commented 9 months ago

Check out this tutorial for example: https://centrifugal.dev/docs/tutorial/intro - it shows how to use subscription object. Just do not use server-side subscriptions at all (i.e. avoid using channels in connection token) - and subscribe with properly constructed subscription token. And it will work. If you still have questions after reading tutorial - please reach out in communities https://centrifugal.dev/docs/getting-started/community - and I'll try to help.