[erlang-questions] Push a message to cowboy websockets

Barco You <>
Sat Apr 7 15:50:48 CEST 2012


Hi AD,

I also tried to implement a websocket broadcast as you did in this mail.
but I got crash in websocket_info as following. Could you please show me
your complete code? thanks!

my code is:

websocket_init(_Any, Req, []) ->
    gproc:reg({p, l,{?MODULE, ?BC}}),
    Req2 = cowboy_http_req:compact(Req),
    {ok, Req2, undefined, hibernate}.

websocket_handle({text, Msg}, Req, State) ->
    broadcast(Msg),
    {reply, {text, << "You said: ", Msg/binary >>}, Req, State, hibernate};
websocket_handle(_Any, Req, State) ->
    {ok, Req, State}.

websocket_info({_Pid, {_Module, ?BC}, Msg}, Req, State) ->

    {reply, {text, <<Msg>>}, Req, State, hibernate}.

broadcast(Msg) ->
    gproc:send({p, l, {?MODULE, ?BC}}, {self(), {?MODULE, ?BC}, Msg}).



** Handler websocket_handler terminating in websocket_info/3

   for the reason error:badarg
** Message was {<0.113.0>,{websocket_handler,
"broadcast"},<<"hello server!">>}
** Options were []
** Handler state was undefined
** Request was [{socket,#Port<0.940>},
                {transport,cowboy_tcp_transport},
                {connection,keepalive},
                {pid,<0.113.0>},
                {method,'GET'},
                {version,{1,1}},
                {peer,undefined},
                {host,undefined},
                {host_info,undefined},
                {raw_host,<<"localhost">>},
                {port,80},
                {path,undefined},
                {path_info,undefined},
                {raw_path,<<"/websocket">>},
                {qs_vals,undefined},
                {raw_qs,<<>>},
                {bindings,undefined},
                {headers,[]},
                {p_headers,[]},
                {cookies,[]},
                {meta,[{websocket_version,13}]},
                {body_state,waiting},
                {buffer,<<>>},
                {resp_state,done},
                {resp_headers,[]},
                {resp_body,<<>>},
                {urldecode,{#Fun<cowboy_http.urldecode.2>,crash}}]
** Stacktrace: [{websocket_handler,websocket_info,3,
                    [{file,"src/websocket_handler.erl"},{line,39}]},
                {cowboy_http_websocket,handler_call,7,
                    [{file,"src/cowboy_http_websocket.erl"},{line,389}]}]


On Sat, Mar 17, 2012 at 4:56 AM, AD <> wrote:

> Sigh, no.  Thanks, its working perfectly now.
>
> -AD
>
>
> On Fri, Mar 16, 2012 at 4:18 PM, Loïc Hoguin <> wrote:
>
>> Did you start gproc? application:start(gproc)
>>
>>
>> On 03/16/2012 09:05 PM, AD wrote:
>>
>>> Thanks, getting some stacktraces though...
>>>
>>> ** Handler ad_test terminating in websocket_init/3
>>>    for the reason error:badarg
>>>
>>> i have
>>>
>>> /-define(WSBroadcast,"**wsbroadcast")./
>>>
>>> then in websocket_init
>>>
>>> /gproc:reg({p, l, {?MODULE, ?WSBroadcast}})/
>>> /
>>>
>>> /
>>> then in my handle() method in cowboy for a certain path
>>>
>>> /{URLPath,_Req2} = cowboy_http_req:path(Req),/
>>> /    case lists:nth(1,URLPath) of/
>>> /<<"sendit">> -> /
>>> /%io:format("Sending websocket !!~n"),/
>>> /Msg = "Test broadcast",/
>>> /gproc:send({p, l, {?MODULE,?WSBroadcast}}, {self(),
>>> {?MODULE,?WSBroadcast}, Msg});/
>>> /
>>> /
>>> then in websocket_info
>>>
>>> w/ebsocket_info({_PID,{_**MODULE,_WSBroadcast},Msg},Req,**State) ->/
>>> /{reply, {text, <<Msg>>}, Req, State, hibernate}./
>>>
>>>
>>> Any thoughts ?  Looks like something with ets:insert
>>>
>>> ** Stacktrace: [{ets,insert_new,
>>>                     [gproc,
>>>                      [{{{p,l,{ad_test,"wsbroadcast"**}},<0.153.0>},
>>> <0.153.0>,undefined},
>>>                       {{<0.153.0>,{p,l,{ad_test,"**
>>> wsbroadcast"}}},[]}]],
>>>                     []},
>>>
>>> Thanks again for the help
>>> -AD
>>>
>>> On Fri, Mar 16, 2012 at 2:06 PM, Loïc Hoguin <
>>> <mailto:>> wrote:
>>>
>>>    Just like you would catch any message, you match:
>>>
>>>    websocket_info({Pid, {Module, WSBroadcast}, Msg}, Req, State)
>>>
>>>    When using gproc:send/2, the second arg is what you want to match in
>>>    the first arg of websocket_info/3. All messages the websocket
>>>    process receives are given to you in websocket_info/3.
>>>
>>>    Didn't try the new pubsub, it looks interesting though.
>>>
>>>
>>>    On 03/16/2012 07:01 PM, AD wrote:
>>>
>>>        Thanks, so in websocket/init
>>>
>>>        gproc:reg({p, l, {?MODULE, WSBroadcast}}).
>>>
>>>        Then in my webservice i can do
>>>
>>>        Msg = "Test broadcast".
>>>        gproc:send({p, l, {?MODULE,WSBroadcast}}, {self(),
>>>        {?MODULE,WSBroadcast}, Msg}).
>>>
>>>        How do you catch this in websocket_info/3 to formulate a reply?
>>>
>>>        Also noticed a new pub/sub module for gproc not sure if this helps
>>>        simplify some of this
>>>        https://github.com/uwiger/__**gproc/blob/master/src/gproc___**
>>> ps.erl<https://github.com/uwiger/__gproc/blob/master/src/gproc___ps.erl>
>>>
>>>        <https://github.com/uwiger/**gproc/blob/master/src/gproc_**ps.erl<https://github.com/uwiger/gproc/blob/master/src/gproc_ps.erl>
>>> >
>>>
>>>        Thanks!
>>>        -AD
>>>
>>>        On Fri, Mar 16, 2012 at 12:20 PM, Loïc Hoguin
>>>        < <mailto:>
>>>        <mailto: <mailto:>>> wrote:
>>>
>>>            Hey!
>>>
>>>            The general idea is to have your websocket handler register
>>>        itself
>>>            using gproc[1] (or through a central gen_server) inside the
>>>            websocket_init/3 callback, and then have your service push
>>>        messages
>>>            to all registered handlers which you can then catch in
>>>        websocket_info/3.
>>>
>>>            I mention gproc because it's infinitely easier with it, as
>>>        you only
>>>            have to register all your processes under one property and
>>>        then send
>>>            a message to that property which will multicast it to all
>>>        registered
>>>            processes. And when your websocket closes, gproc takes care of
>>>            removing your process from the list of registered processes,
>>>        so you
>>>            really have to worry only about 2 lines of code to do
>>>        everything you
>>>            need.
>>>
>>>            Good luck!
>>>
>>>            [1] https://github.com/uwiger/____**gproc<https://github.com/uwiger/____gproc>
>>>        <https://github.com/uwiger/__**gproc<https://github.com/uwiger/__gproc>
>>> >
>>>
>>>        <https://github.com/uwiger/__**gproc<https://github.com/uwiger/__gproc>
>>>        <https://github.com/uwiger/**gproc<https://github.com/uwiger/gproc>
>>> >>
>>>
>>>
>>>
>>>            On 03/16/2012 05:11 PM, AD wrote:
>>>
>>>                Hello,
>>>
>>>                  I have cowboy setup and working to send/receive
>>>        websockets over a
>>>                socket connection.  I am trying to figure out how to
>>>        initiate a
>>>                message
>>>                server side over that channel (without it just being a
>>>        reply).  I am
>>>                envisioning exposing a webservice on the cowboy service
>>> that
>>>                would then
>>>                push a message to all connected users (or maybe a subset
>>>        based
>>>                on some
>>>                criteria).
>>>
>>>                  Does anyone know if this is possible and if so how to
>>>        implement?
>>>
>>>                  Cheers,
>>>                  -AD
>>>
>>>
>>>                ______________________________**_____________________
>>>
>>>                erlang-questions mailing list
>>>         <mailto:erlang-questions@**erlang.org<>
>>> >
>>>        <mailto:**ang.org <http://erlang.org>
>>>        <mailto:erlang-questions@**erlang.org<>
>>> >>
>>>        http://erlang.org/mailman/____**listinfo/erlang-questions<http://erlang.org/mailman/____listinfo/erlang-questions>
>>>        <http://erlang.org/mailman/__**listinfo/erlang-questions<http://erlang.org/mailman/__listinfo/erlang-questions>
>>> >
>>>
>>>
>>>        <http://erlang.org/mailman/__**listinfo/erlang-questions<http://erlang.org/mailman/__listinfo/erlang-questions>
>>>        <http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>>> >>
>>>
>>>
>>>
>>>            --
>>>            Loďc Hoguin
>>>            Erlang Cowboy
>>>            Nine Nines
>>>
>>>
>>>
>>>
>>>    --
>>>    Loïc Hoguin
>>>    Erlang Cowboy
>>>    Nine Nines
>>>
>>>
>>>
>>
>> --
>> Loïc Hoguin
>> Erlang Cowboy
>> Nine Nines
>>
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120407/5214799d/attachment.html>


More information about the erlang-questions mailing list