Search code examples
websocketerlangcowboyn2o

N2O protocol send an empty data when using gproc:send


I created an N2o protocol that routes messages over different family of application, (before that I used a cowboy websocket handler to do this job)

So for example I have this code in my protocol to send a message to a registered process

> info({text,<<"REG:",Msg/binary>> }, Req, State) ->    
> {[{_,Family}]}=jiffy:decode(Msg),     Test = gproc:reg({p, l, Family},
> 1),   {reply, <<"process registered successfully">>, Req, State};




info({text,<<"TRANSMIT:",Msg/binary>> }=M, Req, State) ->
    {[{_,Type},{_,Action},{_,From},{_,To},{_,Message}]}=jiffy:decode(Msg),
     gproc:send({p, l, To}, {self(),<<"Hi I am a good message!">>}),
      {reply, <<"message transmitted successfully">>, Req, State};

In my HTML client , firstly I register under the protocol with

var msg = {family: "JS"}; websocket.send("REG:"+JSON.stringify(msg) );

And I verified that my html process was well registered

Then , From My same HTML client, I called the transmit protocol method like:

msg = {Type: "TRANSMIT:", Action: "Chat", From: "JS", To: "JS", Message:"Hello I am Js"}; websocket.send("TRANSMIT: "+JSON.stringify(msg) );

Basically in this stage I should receive a message contain "Hello I am Js" in my HTML client, but Always I received an empty data string like:

MessageEvent {isTrusted: true, data: "", origin: "ws://192.168.1.20:8000", lastEventId: "", source: null…}

INFO:

I well received the reply message as follows:

when registering process:

MessageEvent {isTrusted: true, data: "process registered successfully", origin: "ws://192.168.1.20:8000", lastEventId: "", source: null…}

when submitting message:

MessageEvent {isTrusted: true, data: "message transmitted successfully", origin: "ws://192.168.1.20:8000", lastEventId: "", source: null…}

Also When I used my cowboy ws handler I didn't experience such issue.


Solution

  • The heart protocol defined client originated messages N2O, PING and server originated messages PONG, IO and NOP. IO message contains EVAL that contains UTF-8 JavaScript string and DATA reply contains any binary string, including BERT encoded data. "PING" and "N2O," are defined as text 4-bytes messages and second could be followed by any text string. NOP is 0-byte acknowledging packet.

    From N2O documentation: http://synrc.com/apps/n2o/doc/web/protocols.htm#sec11

    If you want to violate N2O protocol you should create you own raw custom protocol module:

    -module(protocol).
    -include_lib("n2o/include/wf.hrl").
    -compile(export_all).
    
    event(Event)      -> ok.
    finish(State,Ctx) -> {ok,State,Ctx}.
    init(State,Ctx)   -> wf:reg(topic), {ok,State,Ctx#cx{module=protocol}}.
    
    info({text,Text}=Message, Req, State) -> {reply, Text, Req, State};
    info(Message, Req, State) -> {unknown,Message, Req, State}.
    

    And ensure that only protocol is enabled in sys.config for all handlers:

    {n2o, [{protocols,[protocol]},
           {query,protocol},
           {session,protocol},
           {route,protocol}]},
    

    Usage:

    wscat -c ws://127.0.0.1:9000/
    connected (press CTRL+C to quit)
    > echo
    < echo