Многопользовательские каналы Phoenix
В прошлом я реализовывал мультитенантные системы и использовал заголовок узла запроса для разделения пользователей между арендаторами. Моей первой мыслью было использовать тот же подход, но с веб-сокетами, но я столкнулся с несколькими проблемами:
1) заголовок хоста не доступен
2) Между идентификатором темы и каналом существует отношение один к одному, т.е. если два разных клиента подключаются от разных арендаторов, но к одной и той же теме (например, messages:lobby
) тогда они получат любые сообщения, предназначенные для других арендаторов.
Мне удалось разрешить (1), включив параметр запроса, идентифицирующий клиента в строку подключения веб-сокета. (2), где вещи немного неясно. Я мог бы назвать пространство тем для включения идентификатора арендатора, например tenant1:messages:123
, но теперь есть две переменные в теме, так что вы не можете сопоставить функции на что-то вроде tenant_id <> ":messages:" <> message_id
, Вы можете обойти это с помощью одной функции, но в ней много работы.
Есть ли лучшая стратегия для мультитенантных веб-сокетов?
1 ответ
Извиняюсь за то, что написал это как ответ вместо комментария, но у меня пока нет 50 репутации.
Вместо того, чтобы добавлять tenant_id, почему бы не сделать так, чтобы тема выглядела как messages:tenant1:123
?
Вы можете создать образец соответствия для функции, затем просто разделить идентификаторы и передать их функции, которая фактически потребляет их:
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