ericmoritz / wsdemo

A Cowboy Websocket demo
Other
405 stars 58 forks source link

clojure version does not handshake with the erlang client #33

Closed aglyzov closed 12 years ago

aglyzov commented 12 years ago

I tried to test the provided clojure server, here is what I got:

"clojure", 10000, 0, 2754, 0, 0, 0

I think this means the aleph library used in the server speaks some older websocket dialect.

r4vi commented 12 years ago

I couldn't get the erlang client to work so I've only tested with chrome. I'll spend some time trying to fix the erlang client on my machine & see if I can debug this.

Possibly won't be able to do it before the weekend though. :(

ericmoritz commented 12 years ago

I'll check into it today. Did runtest spew out a ton of errors?

aglyzov commented 12 years ago

I've just rerun the test with just 10 connections for 10 seconds to reduce the problem field:

$ ./runtest data/clojure 10 192.168.1.2 8080 10 Running test with 10 clients for 10 seconds Data File: "data/clojure" Running logger queue: 0 Elapsed: 0s of 10s Finished

type, clients, handshakes, connection_timeouts, messages_sent, messages_recv, crashes "clojure", 10, 0, 0, 0, 0, 0

Note, the port is right, the clojure server uses 8080 instead of 8000. So, as you can see, no rough errors like connection timeouts, but yet no handshakes.

aglyzov commented 12 years ago

Ravi, I can help you to setup erlang/rebar if you're on ubuntu or debian. I already did this a dozen times recently :)

ericmoritz commented 12 years ago

Hmm. Alphe uses Netty which looks like it supports Websockets version 13. That is the version my client is targeting.

May sample version 13 request doesn't successfully handshake:

cat request.txt | nc localhost 8080

That simply returns.

I sent your clojure server the exact request that is in the Netty docs for version 13 and it exhibits the same behavior:

https://github.com/netty/netty/blob/master/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java#L82

I have tracked the issue down to this cause. It appears that the Clojure server does not like that I am sending the Sec-WebSocket-Protocol: chat header:

    $ git diff request.txt
    diff --git a/request.txt b/request.txt
    index 4a5ecb5..13f6bbe 100644
    --- a/request.txt
    +++ b/request.txt
    @@ -4,6 +4,5 @@ Connection: Upgrade
    Host: localhost
    Origin: http://localhost/
    Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
    -Sec-WebSocket-Protocol: chat
    Sec-WebSocket-Version: 13

    $ cat request.txt | nc localhost 8080
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

Chrome 19 is not sending the "Sec-WebSocket-Protocol: chat" header. I'll look into why I thought it was required (It is probably copy pasta from the spec)

aglyzov commented 12 years ago

ah! I remember now I had the same issue with the twisted websocket implementation (txWS). when I tweaked the server to accept any Sec-WebSocket-Protocol it interoperated fine!

btw, the websocket RFC states this header is to define a sub-protocol (on top of websocket transport). so the questions is can you omit sending it altogether? thus I would be able to also add a vanilla twisted websocket server.

ericmoritz commented 12 years ago

So, yes that was copy pasta.

What I've gleaned in the past 10 minutes of Googling is that the Sec-WebSocket-Protocol defines a subprotocol that both the client and server needs to agree that they speak. I suppose that Netty is probably the only server that enforces this by default. I bet the following exception is being swallowed up somehow and if we enable logging on the Clojure server we'll see it:

https://github.com/netty/netty/blob/master/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocketServerHandshaker13.java#L138

aglyzov commented 12 years ago

probably

ericmoritz commented 12 years ago

Yup, Chrome breaks if I provide the send argument of ["chat"]. Looks like we have a winner.

ericmoritz commented 12 years ago

I'll remove the header from my client for now

ericmoritz commented 12 years ago

Works perfectly, pushing to master now.

aglyzov commented 12 years ago

works here too. clojure is slower than java, no miracles today

ericmoritz commented 12 years ago

I'm surprised that Clojure does much worse, it's just a wrapper around the same library. searching google Actually, it looks like Webbit is not using the built-in Netty websocket implementation. I should probably do a native Netty server using their implementation.

I wonder if that is the source of the slower times. It would be interesting to know if Webbit beats Netty's implementation.