Code Monkey home page Code Monkey logo

Comments (4)

FZambia avatar FZambia commented on June 15, 2024

Hello @ghstahl

Generally it works as expected, but you have a rather unusual combination on client-side which caused client SDK to skip publication processing for server-side subscription.

To fix, in your app code move entire client-side subscription logic into the !WithChannelToken condition (not only sub.Subscribe() as it's now). I.e.:

if !WithChannelToken {
	sub, err := client.NewSubscription(internal.Channel,
		centrifuge.SubscriptionConfig{
			Recoverable: true,
			JoinLeave:   true,
			Positioned:  true,
		})
	if err != nil {
		subscriptionLog.Fatal().Err(err).Msg("failed to create subscription")
	}
	sub.OnSubscribed(func(e centrifuge.SubscribedEvent) {
		subscriptionLog.Info().Interface("event", e).Msg("OnSubscribed")
	})
	sub.OnError(func(e centrifuge.SubscriptionErrorEvent) {
		subscriptionLog.Error().Interface("event", e).Msg("OnError")
	})
	sub.OnUnsubscribed(func(e centrifuge.UnsubscribedEvent) {
		subscriptionLog.Info().Interface("event", e).Msg("OnUnsubscribed")
	})
	sub.OnPublication(func(e centrifuge.PublicationEvent) {
		subscriptionLog.Info().Interface("event", e).Msg("OnPublication")
	})

	// Subscribe on private channel.
	err = sub.Subscribe()
	if err != nil {
		subscriptionLog.Fatal().Err(err).Msg("failed to subscribe")
	}
	subscriptionLog.Info().Msg("sub.Subscribe")
}

Because calling client.NewSubscription(internal.Channel adds channel to the internal registry, and this interferes with server-side channel during processing of message coming from a server.

I am not sure at this point whether it may be somehow improved on SDK level - will try to think on it.

from centrifugo.

ghstahl avatar ghstahl commented on June 15, 2024

Ok, that worked for both cases.

One approach to normalization of the SDK is to do a formal subscribe ceremony like I do with the caps token for everything.

Don't do the subscribe here if you see a token with the channels claim.

err = client.Connect()

This should only mean that you can connect to the centrifugo server.

The jwt is just there to deny your formal .Subscribe if there is no match

i.e. fail this call.

err = sub.Subscribe()

from centrifugo.

ghstahl avatar ghstahl commented on June 15, 2024

This introduces a 2 path problem as well for subscribing.

  1. I have to evaluate the token to determine the path. i.e. does it have caps or channels as a claim.
  2. The OnSubscribed handler is different. The client.OnSubscribed() handler gets called when I use the channels token, and the sub.OnSubscribed() handler gets called when I use the caps token.

I favor a single subscribe ceremony so that there is only one OnSubscribed() handler. The token with channels starts introducing surprises.

I guess since I am responsible for creating the JWTs, I can decide to NEVER create a jwt with the channels claim.

So I would have a JWT that might look like this.

{
   "caps":{},
   "allowed_channels":[]
}

It means that my code is the one doing a pre-check on that JWT before I use it to connect to centrifugo.

Your SDK is good, I just can't use the channels tokens and I get my singular way to subscribe to a channel. The CAPS way.

from centrifugo.

FZambia avatar FZambia commented on June 15, 2024

Yep, you are of course free to proceed just with caps if having channels brings confusion. You can make a rule to use them in different namespaces also. Actually caps is about permissions, while channels is a way to subscribe to server-side channels. They serve different purpose semantically. BTW in the doc we generally recommend to go with client-side subscriptions because they come with more flexibility and granularity. Mixing different types of subscriptions for the same channel is actually considered more a developer mistake, though I guess SDKs could be more friendly to signal about this. Usually already subscribed error serves good enough, this particular case you came across is a rather rare situation I believe - possible to improve somehow, but seems minor.

from centrifugo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.