centrifuge-go
centrifuge-go copied to clipboard
Tags for Publish
When OnPublished
is called for a message received on a subscribed channel, the Publication
struct has a Tags
member which matches up with tags
as described on https://centrifugal.dev/docs/transports/client_api ("optional tags, this is a map with string keys and string values"), however when client.Publish
or subscription.Publish
is called, there is no field allowing for tags
to be added.
Am I misunderstanding the client API vs the server API? Can tags only be specified on the server side?
Hello @shaunco
Yes, at this point tags can only be attached to Publication using server API. Centrifugo model is mostly built around using server API for publishing (as you can find here). Also, while technically possible, I am not sure that we want tags in client API because it will mean more possible fields for backend to validate before accepting a publication.
Thanks @FZambia! I think my confusion arises from not seeing another go library for use between the App backend <---> Centrifugo
(in the idiomatic usage link you provided) that makes use of the server API, which means if I have go based backend apps/services publishing to (subscribing) to Centrifugo and go based clients subscribing to various channels, both end up using this centrifuge-go library.
Since my particular usecase is sending protobuf payloads, I will just embed the additional fields I was thinking of putting into tags
into my protobuf payload.
To expand on that further, there are many pub/sub use cases where there is no need to "validate before accepting a publication" - simply holding a valid token usable by Centrifugo is enough validation. The two examples that come to mind are:
- Two
App backend
services that are both publishing and subscribing to channels - IoT uses cases where the
client
is some form of edge gateway (running code written and managed by the same entity that writes theApp backend
) is publishing events/data to a Centrifugo channel that are picked up by anApp backend
that is subscribing to device-specific channels. Conversely, the edge gateway also subscribes to receive commands that are published by theApp backend
. (This IoT use case is one of the more popular use cases for PubNub)
Neither case has the concept of an untrusted client that needs a different API or to have its publications validated before going to Centrifugo, but from an SDK standpoint, centrifuge-go appears to be the best (and only) option for a go package. I understand that gRPC can be used directly (as shown here) the generated gRPC client is missing things like auto-reconnect (with exponential backoff), auto-resubscribe, auto-recovery, and more that makes it fine when an App backend
is doing an occasional publish, but not very useful if the App backend
needs to subscribe.
Am I missing something here?
All the thoughts are totally valid, some things I can add:
- We also have https://github.com/centrifugal/gocent SDK for server API if you missed it, though it does not support adding Tags yet - but nothing prevents us to extend it. But your considerations about GRPC API apply to
gocent
also. Though probably publishing using server API from trusted env is actually not so bad idea. - As I mentioned, passing tags from client side will require backend validate the tags also in many cases. So adding possibility to attach tags over the client API will require thinking how to manage this properly from the permission side of view. I don't have clear answer to this yet - with a simple
data
field it's pretty obvious and intuitive, with more fields it's becoming harder.
So before adding Tags to client API in some way, I suppose it's required to think how to add them to current permission model, probably we can make propagating tags explicit somehow - so backend does not have a chance to forget about tags field and propagate them without validation.
So let's think more whether it's possible, and keep this issue open. It's not a quick addition, so probably for now you need to use alternative way with adding information to data payload or using server API client.
Thanks! I had missed gocent. Happy to move this from an Issue to a Discussion, or keep it here, but I appreciate the openness to thinking about IoT use cases!
We have a dedicated Envelope
protobuf message that wraps all the actual protobuf messages we put into the data
field, so we can just move ahead with adding our various headers to our Envelope
rather than using tags
.