@ nmichaels answer указал мне верное направление, и я успешно использовал gen_event в приложении для ковбоев для отправки внутренних сообщений в websocket_info.Но ответ немного устарел, и ковбой сильно изменился, поэтому я хотел бы добавить к нему и предложить решение, которое работает на последней версии ковбоя.Надеюсь, это поможет кому-то новому для Эрланга и ковбоя.
Для реализации gen_event в ковбое необходимо выполнить три шага
Запустить gen_event и зарегистрировать ваши обработчики
start(_Type, _Args) ->
Dispatch = cowboy_router:compile(wrinqle_routes:routes_configuration()),
{ok, _} = cowboy:start_http(http, 100, [{port, 3000}],
[{env, [{dispatch, Dispatch}]}]),
pg2:start(),
gen_event:start({global,my_events}),
gen_event:add_handler({global,my_events},my_event_handler,[]).
Здесь я зарегистрировал событие my_events глобально (примечание: вы также можете зарегистрировать события локально) и добавил обработчик в модуль my_event_handler
Создайте обработчик события.
Теперь вы можете уведомлять обработчик событий о событиях из любой точки ковбоя.В качестве примера приведенный ниже код вызывает события из websocket_handler
{ _,_ }->
gen_event: notify(global:whereis_name(my_events),{event_name,self()}),
{ok,Req,State};
Все, что делает этот код, - это оповещение о событии, зарегистрированном в my_events, о глобальном событии.Вот и все.
Другая проблема, с которой столкнулся ОП, заключалась в том, как отправлять сообщения об открытых соединениях и соединениях, для которых pid не известен во время инициализации.Для решения этой проблемы вы можете использовать pg2 , который регистрирует идентификатор процесса по каналам.Это очень полезный модуль для управления PID.Таким образом, приведенный выше код может быть преобразован во что-то вроде этого
[H|T] = pg2:get_members(Name)
gen_event: notify(global:whereis_name(my_events),{event_name, H}).
И таким образом вы можете отправлять сообщения на определенный pid и, соответственно, на конкретный сокет.