Communication between http handler and websocket handler in Cowboy
I would like to create a websocket application in Cowboy that receives its data from another Cowboy handler. Let's say that I want to combine an Echo_get example from a cowboy: https://github.com/ninenines/cowboy/tree/master/examples/echo_get/src
with websocket example
https://github.com/ninenines/cowboy/tree/master/examples/websocket/src
such that the GET request for Echo should send a "push" through the websocket handler to the html page in this example.
What's the least tricky way to do this? Can I use the pipe operator in some simple way? Do I need to create and intermediate gen_something to pass messages between them? I would appreciate an answer with a sample code that shows the glue code for the handlers - I really don't know where to start connecting the two handlers together.
source to share
The websocket handler in cowboys is a long running request process that you can send websocket or erlang messages to.
In your case, there are two types of processes:
- websocket processes: websocket handlers with a connection to a website open to clients.
- Echo Processes: Processes where a client accesses an echo handler with a parameter.
The idea is that the echo process will send an erlang message to the websocket processes, which in turn will send a message to the client.
In order for your ping process to be able to send a message to your network processes, you need to keep a list of the webcast processes to which you want to send messages. Gproc is a pretty useful library for this purpose.
You can register processes in gproc pubsub with gproc_ps:subscribe/2
and send messages to registered processes with gproc_ps:publish/3
.
Cowboy web mailing processes receive erlang messages using the websocket_info / 3 function .
So, for example, a websocket handler could be like this:
websocket_init(_, Req, _Opts) ->
...
% l is for local process registration
% echo is the name of the event you register the process to
gproc_ps:subscribe(l, echo),
...
websocket_info({gproc_ps_event, echo, Echo}, Req, State) ->
% sending the Echo to the client
{reply, {text, Echo}, Req, State};
And the echo handler looks like this:
echo(<<"GET">>, Echo, Req) ->
% sending the echo message to the websockets handlers
gproc_ps:publish(l, echo, Echo),
cowboy_req:reply(200, [
{<<"content-type">>, <<"text/plain; charset=utf-8">>}
], Echo, Req);
source to share