bwegh / erwa

Please use https://github.com/CargoTube/cargotube or https://github.com/CargoTube/ct_erwa_api instead.
MIT License
57 stars 16 forks source link

Not working with AutobahnPython client, any ideas? #5

Closed mriehl closed 10 years ago

mriehl commented 10 years ago

Hi,

I'm trying to use a variant of the simple router with the python autobahn client. The websocket connection upgrade works, but the simple router does not reply to the clients WAMP HELLO message:

2014-09-02 11:48:34+0200 [WampWebSocketClientProtocol,client] received HTTP status line in opening handshake : HTTP/1.1 101 Switching Protocols
2014-09-02 11:48:34+0200 [WampWebSocketClientProtocol,client] received HTTP headers in opening handshake : {u'connection': u'Upgrade', u'upgrade': u'websocket', u'sec-websocket-protocol': u'wamp.2.json.batched', u'sec-websocket-accept': u'zE8eNRgwuukgfNNzweN+kOauVCg='}
2014-09-02 11:48:34+0200 [WampWebSocketClientProtocol,client] TX WAMP HELLO Message (realm = realm1, roles = [<autobahn.wamp.role.RolePublisherFeatures instance at 0x7f73dda7cdd0>, <autobahn.wamp.role.RoleSubscriberFeatures instance at 0x7f73dda7ce18>, <autobahn.wamp.role.RoleCallerFeatures instance at 0x7f73dda7ce60>, <autobahn.wamp.role.RoleCalleeFeatures instance at 0x7f73dda7cea8>], authmethods = None, authid = None)
2014-09-02 11:48:34+0200 [WampWebSocketClientProtocol,client] TX Frame to 172.17.0.3:8080 : fin = True, rsv = 0, opcode = 1, mask = ebdc4880, length = 78, repeat_length = None, chopsize = None, sync = False, payload = [1,"realm1",{"roles":{"subscriber":{},"publisher":{},"caller":{},"callee":{}}}]
2014-09-02 11:48:34+0200 [WampWebSocketClientProtocol,client] TX Octets to 172.17.0.3:8080 : sync = False, octets = 81ceebdc4880b0ed64a292bd2cf4c9f033a299b324e598fe72fbc9af3de298bf3ae989b93aa2d1a735acc9ac3de287b53be88eae6aba90a164a288bd24ec8eae6aba90a164a288bd24ec8eb96aba90a135fdb6c4
# no response from server

Do you have an idea what the problem could be?

mriehl commented 10 years ago

Found the problem.

The AutobahnPython client asks for

[<<"wamp.2.json.batched">>,
 <<"wamp.2.json">>]

by default as a transfer protocol.

And then you have lines 51pp in erwa_ws_handler.erl with

  case lists:nth(1,Protocols) of
      ?WSMSGPACK ->
        Req2  = cowboy_req:set_resp_header(?SUBPROTHEADER,?WSMSGPACK,Req1),
        {ok,Req2,#state{enc=msgpack}};
      ?WSMSGPACK_BATCHED ->
        Req2  = cowboy_req:set_resp_header(?SUBPROTHEADER,?WSMSGPACK_BATCHED,Req1),
        {ok,Req2,#state{enc=msgpack_batched}};
      ?WSJSON ->
        Req2  = cowboy_req:set_resp_header(?SUBPROTHEADER,?WSJSON,Req1),
        {ok,Req2,#state{enc=json}};
      ?WSJSON_BATCHED ->
        Req2  = cowboy_req:set_resp_header(?SUBPROTHEADER,?WSJSON_BATCHED,Req1),
        {ok,Req2,#state{enc=json_batched}};
      _ ->
        {shutdown,Req1}

So this takes the first offered protocol (json batched) and tries to use that. Unfortunately the wamp part does not support batched json and simply ignores the requests.

bwegh commented 10 years ago

Hi, Thank you for the Feedback.

Which wamp Part does not support batched mode? Python Autobahn or Erwa? As Erwa should work, if not please let me know.

Cheers, Bas

mriehl commented 10 years ago

Hi @bwegh ,

actually erwa doesn't fully support batched json if I understand it correctly. The websocket_init code supports it (?WSJSON_BATCHED in erwa_ws_handler.erl:61) but then websocket_handle silently skips everything that is not json or msgpack encoded:

websocket_handle({text, Data}, Req, #state{enc=json}=State) ->
  {ok,NewState} = handle_wamp(Data,State),
  {ok,Req,NewState};
websocket_handle({binary, Data}, Req, #state{enc=msgpack}=State) ->
  {ok,NewState} = handle_wamp(Data,State),
  {ok,Req,NewState};
websocket_handle(_Data, Req, State) ->
  {ok, Req, State}.

As you can see this will only dispatch to handle_wamp if enc=json or enc=msgpack and ignore it otherwise.

bwegh commented 10 years ago

Hello @mriehl , could you please see if the latest version fixes this issue. I have right now little time for testing. Thanks a lot.

mriehl commented 10 years ago

Hi,

I tried the simple router example after pulling in e0edad1031c2bf83c65b28c7b5828704d6a04ce3. This now leads to another problem:

=ERROR REPORT==== 4-Sep-2014::13:01:54 ===
Error in process <0.194.0> on node 'simple_router@127.0.0.1' with exit value: {[{reason,badarg},{mfa,{erwa_ws_handler,websocket_handle,3}},{stacktrace,[{jsx_decoder,done,4,[{file,"src/jsx_decoder.erl"},{line,936}]},{erwa_protocol,'-deserialize/3-fun-0-',2,[{file,"src/erwa_protocol.erl"},{line,57}]},{lists... 

=ERROR REPORT==== 4-Sep-2014::13:01:54 ===
Ranch listener http had connection process started with cowboy_protocol:start_link/4 at <0.194.0> exit with reason: {[{reason,badarg},{mfa,{erwa_ws_handler,websocket_handle,3}},{stacktrace,[{jsx_decoder,done,4,[{file,"src/jsx_decoder.erl"},{line,936}]},{erwa_protocol,'-deserialize/3-fun-0-',2,[{file,"src/erwa_protocol.erl"},{line,57}]},{lists,foldl,3,[{file,"lists.erl"},{line,1261}]},{erwa_protocol,deserialize,3,[{file,"src/erwa_protocol.erl"},{line,57}]},{erwa_ws_handler,handle_wamp,2,[{file,"src/erwa_ws_handler.erl"},{line,105}]},{erwa_ws_handler,websocket_handle,3,[{file,"src/erwa_ws_handler.erl"},{line,73}]},{cowboy_websocket,handler_call,7,[{file,"src/cowboy_websocket.erl"},{line,589}]},{cowboy_protocol,execute,4,[{file,"src/cowboy_protocol.erl"},{line,435}]}]},{msg,{text,<<91,49,44,34,121,97,100,116,34,44,123,34,114,111,108,101,115,34,58,123,34,115,117,98,115,99,114,105,98,101,114,34,58,123,125,44,34,112,117,98,108,105,115,104,101,114,34,58,123,125,44,34,99,97,108,108,101,114,34,58,123,125,44,34,99,97,108,108,101,101,34,58,123,125,125,125,93,24>>}},{req,[{socket,#Port<0.814>},{transport,ranch_tcp},{connection,keepalive},{pid,<0.194.0>},{method,<<"GET">>},{version,'HTTP/1.1'},{peer,{{172,17,42,1},39456}},{host,<<"node1">>},{host_info,undefined},{port,8080},{path,<<"/wamp">>},{path_info,undefined},{qs,<<>>},{qs_vals,undefined},{bindings,[]},{headers,[{<<"user-agent">>,<<"AutobahnPython/0.8.15">>},{<<"host">>,<<"node1:8080">>},{<<"upgrade">>,<<"WebSocket">>},{<<"connection">>,<<"Upgrade">>},{<<"pragma">>,<<"no-cache">>},{<<"cache-control">>,<<"no-cache">>},{<<"sec-websocket-key">>,<<"1HfkAh9zkC0ievIgAfMQiQ==">>},{<<"sec-websocket-protocol">>,<<"wamp.2.json.batched">>},{<<"sec-websocket-version">>,<<"13">>}]},{p_headers,[{<<"sec-websocket-protocol">>,[<<"wamp.2.json.batched">>]},{<<"upgrade">>,[<<"websocket">>]},{<<"connection">>,[<<"upgrade">>]}]},{cookies,undefined},{meta,[{websocket_version,13},{websocket_compress,false}]},{body_state,waiting},{buffer,<<>>},{multipart,undefined},{resp_compress,false},{resp_state,done},{resp_headers,[]},{resp_body,<<>>},{onresponse,undefined}]},{state,{state,json_batched,undefined,<<>>}}],[{cowboy_protocol,execute,4,[{file,"src/cowboy_protocol.erl"},{line,435}]}]}
bwegh commented 10 years ago

Hi @mriehl ,

It is working for me with a javascript websocket client using json, the test checks if a batched is forced to json and it is. Could you please test with your client and confirm this.

Thanks for your feedback, Bas

mriehl commented 10 years ago

Hi @bwegh ,

I pulled in your changes and it works like a charm now. As long as the client supports json this is what the server forces. Thanks a lot for your help and for your work on erwa!

bwegh commented 10 years ago

Great to hear it is working for you. Yes at the moment erwa is enforcing json or msgpack in non batched mode.

I already opened an enhacement issue to implement the batched versions

Cheers, Bas