@nmichaels answer pointed me in the right direction, and I successfully used gen_event in a cowboy app to send internal messages to websocket_info. But the answer is a little outdated and the cowboy has changed a lot, so I would like to add to it and provide a solution that will work with the latest version of the cowboy. Hope this helps someone new Erlan and the cowboy.
To implement gen_event in cowboys
You must complete three steps:
Run gen_event and register handlers
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,[]).
Here I logged an event called my_events globally (note: you can also log events locally) and a handler is added in the my_event_handler module
Create an event handler.
Now you can notify the event handler of events from anywhere in the cowboy. As an example, the code below raises events from websocket_handler
{ _,_ }-> gen_event: notify(global:whereis_name(my_events),{event_name,self()}), {ok,Req,State};
All this code makes a notification of an event registered in my_events around the world of the event. What is it.
Another problem OP was facing was how to send messages to open connections and connections for which pid is not known during initialization. To solve this problem, you can use pg2 , which registers the process identifier by channel. This is a very useful PID management module. So the above code can be converted to something like this
[H|T] = pg2:get_members(Name) gen_event: notify(global:whereis_name(my_events),{event_name, H}).
And in this way you can send a message to a specific pid and by extension to a specific socket.
source share