Reputation: 30231
In the past I've implemented multi tenant systems and used the request host header to segregate users between tenants. My first thought was to take the same approach but with websockets but I hit a couple of issues:
1) The host header does not appear to be available
2) There's a one to one relationship between a topic id and the channel i.e. if two different clients connect from different tenants but to the same topic (e.g. messages:lobby
) then they will receive any messages meant for other tenants.
I've been able to resolve (1) by including a query param identifying the tenant in the websocket connect string. (2) is where things are a little unclear. I could namespace the topics to include the tenant's identifier, e.g. tenant1:messages:123
, but there's now two variables in the topic so you can't match functions on something like tenant_id <> ":messages:" <> message_id
. You can workaround this with a single function but there's a lot of boilerplate going on.
Is there a better strategy for multi-tenant websockets?
Upvotes: 0
Views: 531
Reputation: 136
Apologies for writing this as an answer instead of a comment but I don't have the 50 reputation yet.
Instead of prepending the tenant_id, why not have the topic look something like messages:tenant1:123
?
You could pattern match on a function, then just split the ids and pass them along to the function that actually consumes them:
def foo("messages:" <> ids) do
[tenant_id, message_id] = String.split(ids, ":")
bar(tenant_id, message_id)
end
def bar(tenant_id, message_id) do
# Do something
end
Upvotes: 2