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?