Dynamically change channel topic on join

I am building a real-time application where channel topics will be split by tenant_id, so for example channel "events:" <> tenant_id.

However I would like for the client to be able to join without including the tenant_id ie:

socket.channel("events").join()

I am doing the authorization and setting the tenant_id on the socket assigns upon socket connection so I don’t have any security concerns.

Here’s the code.

def join("events", _payload, socket) do
	socket_user_id = socket.assigns.token_data.user_id
	socket_tenant_id = socket.assigns.token_data.tenant_id
	
	#Can I dynamically change the topic name from events to event <> socket_tenant_id here?
	
	Logger.info("#{socket_user_id} joined events:#{socket_tenant_id}")
	{:ok, socket}       
end
#Can I dynamically change the topic name from events to event <> socket_tenant_id here?

You can subscribe to additional topic from within the join function:

#Can I dynamically change the topic name from events to event <> socket_tenant_id here?
YourAppWeb.Endpoint.subscribe("events:" <> socket_tenant_id)

You’d be receiving broadcasts for both events and events:<tenant-id> topics. I don’t think there is a way to change the channel topic from within its join function that wouldn’t lead to more problems.

Not possible. Send the tenant id or a value which can look up tenant to client and send it up as part of the topic.

2 Likes

Thanks @chrismccord - good to know.

Coming from an OOP background but trying to think in a more functional / Elixir way I guess a reason for this is changing the topic inside the join would be a potentially hidden side effect and an anti-pattern?