Передача сообщений всем подключенным пользователям с помощью веб-сокета (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, и автоматически удалить его из списка регистрации.

Жизнь обработчика может выглядеть примерно так:

  1. websocket_init/3 вызывается после того, как Cowboy выполняет обновление протокола, запрошенное в init/3 (в WebSocket). Отсюда, клиентский обработчик регистрируется с broadcastПроцесс трансляции сообщений.
  2. Пока соединение остается открытым, обработчик получает широковещательные сообщения на свой websocket_info/3, передавая сообщения клиенту, возвращая {reply, {text, Message}, State},
  3. По окончании обработчик отменяет регистрацию broadcast, Если по какой-то причине это не работает, как задумано, broadcast держит мониторы на всех подписчиках, чтобы получать уведомления об их смерти.

Каждый процесс ковбоя получает свою очередь Кролика. Трансляция будет работать с подстановочными символами. Явный цикл не задействован. Вы можете сделать подписку необязательной, не связывая ее соответствующим образом. Смотрите: Как настроить очередь таким образом, чтобы все подписчики получали сообщения - Rabbit MQ

Другие вопросы по тегам