[erlang-questions] Push a message to cowboy websockets
Barco You
barcojie@REDACTED
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 <straightflush@REDACTED> wrote:
> Sigh, no. Thanks, its working perfectly now.
>
> -AD
>
>
> On Fri, Mar 16, 2012 at 4:18 PM, Loïc Hoguin <essen@REDACTED> 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 <essen@REDACTED
>>> <mailto:essen@REDACTED>> 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
>>> <essen@REDACTED <mailto:essen@REDACTED>
>>> <mailto:essen@REDACTED <mailto:essen@REDACTED>>> 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
>>> erlang-questions@REDACTED <mailto:erlang-questions@**erlang.org<erlang-questions@REDACTED>
>>> >
>>> <mailto:erlang-questions@REDACTED**ang.org <http://erlang.org>
>>> <mailto:erlang-questions@**erlang.org<erlang-questions@REDACTED>
>>> >>
>>> 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
> erlang-questions@REDACTED
> 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.htm>
More information about the erlang-questions
mailing list