Передача сообщений всем подключенным пользователям с помощью веб-сокета (Erlang, RabbitMQ, Websocket, Gen_bunny, Cowboy)
Я пытаюсь интегрировать чат через веб-сокет, используя ERlang, Cowboy, Websocket и gen_bunny.
Я могу заставить их работать самостоятельно.
Браузер -> Ковбойский веб-сокет-чат (Работы) Erlang и RabbitMQ AMQP (Работы)
При их объединении я могу получить сообщение из браузера в Cowboy, передать его RabbitMQ и снова вернуть его из RabbitMQ.
Я даже могу ответить на сообщение пользователю, который его отправил. Тем не менее, я хочу передать сообщение всем подключенным пользователям.
Насколько я понимаю, Erlang создаст отдельный процесс для каждого пользователя. Итак, как передать его всем подключенным пользователям после того, как я получу ответ от RabbitMQ??
3 ответа
Посмотрите на проект gproc: https://github.com/uwiger/gproc
У него есть шаблон Pub/Sub, который вы можете использовать для создания чата, который вы упомянули.
Из вики gproc:
subscribe(EventType) ->
%% Gproc notation: {p, l, Name} means {(p)roperty, (l)ocal, Name}
gproc:reg({p, l, {?MODULE, EventType}}).
notify(EventType, Msg) ->
Key = {?MODULE, EventType},
gproc:send({p, l, Key}, {self(), Key, Msg}).
Правильно -Cowboy создает процесс для каждого соединения, который запускает ваш код обработчика WebSocket. Один подход заключается в том, чтобы иметь websocket_init/3
функция регистрирует себя с помощью "широковещательного" процесса (и отменяет регистрацию в websocket_terminate/3
). После получения сообщения от RabbitMQ процесс вещания повторяет сообщение для всех зарегистрированных подключений WebSocket, которые могут получить его, используя websocket_info/3
обработчик обратного вызова.
Процесс широковещания может использовать мониторы, чтобы обнаружить, когда умирает обработчик WebSocket, и автоматически удалить его из списка регистрации.
Жизнь обработчика может выглядеть примерно так:
websocket_init/3
вызывается после того, как Cowboy выполняет обновление протокола, запрошенное вinit/3
(в WebSocket). Отсюда, клиентский обработчик регистрируется сbroadcast
Процесс трансляции сообщений.- Пока соединение остается открытым, обработчик получает широковещательные сообщения на свой
websocket_info/3
, передавая сообщения клиенту, возвращая{reply, {text, Message}, State}
, - По окончании обработчик отменяет регистрацию
broadcast
, Если по какой-то причине это не работает, как задумано,broadcast
держит мониторы на всех подписчиках, чтобы получать уведомления об их смерти.
Каждый процесс ковбоя получает свою очередь Кролика. Трансляция будет работать с подстановочными символами. Явный цикл не задействован. Вы можете сделать подписку необязательной, не связывая ее соответствующим образом. Смотрите: Как настроить очередь таким образом, чтобы все подписчики получали сообщения - Rabbit MQ