Passing data from consumer to channel layer used outside in another script

I am looking for a way to pass extra data from WS subscription to be used later using channel layer Using outside of consumers.

My use case is:

  • The client sub is something like {'model': 'App.Model', 'a': 'b'}
  • Consumer creates a group named ‘App.Model’ using await self.channel_layer.group_add(app_model, self.channel_name)
  • Tasks script is running periodically and sends model updates to each group.

I need to pass a=b somehow from the consumer, so I can use it in the broadcasting job, apparently there’s no way to do so, since storing the variable in scope isn’t accessible outside the consumer. Also there’s no way to check if a group name exists, so I can set group name to App.Model_b and check for it later.

Rather than trying to describe what you want in terms of a solution, can you try to explain what it is you’re looking to achieve in terms of the results wanted? More details about your objective and requirements would be helpful.

Note, the scope isn’t something for you to store data in. However, the consumer is. If you need to retain data within a consumer, store it as attributes on the consumer itself.

In the general case, you can pass data between components either through a channel or the database.

Users can subscribe to updates of a specific object. Eg, given a Document model, they can subscribe to id=1, and will receive any updates from ws for Document(id=1).

Updates are sent by the job scheduler (apscheduler). It checks for any document updates, then sends to each user the updates of the document(s) they are subscribed to.

That last part is where I’m having trouble. How to know which connected ws users are subscribed to which documents?

Is the most efficient approach creating a room for each document?

Absolutely. There’s no need, reason, or benefit to doing this any other way.

Rooms are a very “lightweight” structure. If you’re using the redis back end, it’s a key containing the channels connected to it. (That’s also why they’re non-iterable regarding who, or what, has joined a room.)

If you have a need to know what specific users are connected to a document, then you need to use something like django-channels-presence to provide that functionality.

Thanks Ken, that’s helpful!

I should send to the ‘document-{id}’ room, without checking if that room exists, right?

Correct. Assuming you’re using the redis backend, it doesn’t matter. Redis doesn’t care if the key exists or not.