3
votes

I have the same question that was asked in another post except I'm having the issue in version 13 (RFS 6455). Has anyone succeeded in implementing a web socket server using this version? I've tried all the other suggestions I could find, but none of them worked.

Related Post: Websocket server: onopen function on the web socket is never called.

Client is javascript on Chrome 16. Server is a C# console application.

My server is able to receive the client handshake and successfully send a response, but the onopen/onmessage event is not being triggered on the client.

It seems the issue for most people online is with the handshake message itself, but all the examples I can find are for -75 or -76 version.

I am following the instructions here: http://tools.ietf.org/html/rfc6455#page-39

Here I initialize my server handshake response.

handshake = "HTTP/1.1 101 Switching Protocols" + Environment.NewLine;
handshake += "Upgrade: websocket" + Environment.NewLine;
handshake += "Connection: Upgrade" + Environment.NewLine;
handshake += "Sec-WebSocket-Accept: ";

This is where I receive the client handshake message, generate my response key and send it back.

System.Text.ASCIIEncoding decoder = new System.Text.ASCIIEncoding();
string clientHandshake = decoder.GetString(receivedDataBuffer, 0, receivedDataBuffer.Length);
string[] clientHandshakeLines = clientHandshake.Split(new string[] { Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries);

foreach (string line in clientHandshakeLines)
{
    if (line.Contains("Sec-WebSocket-Key:"))
    {
        handshake += ComputeWebSocketHandshakeSecurityHash09(line.Substring(line.IndexOf(":") + 2));
        handshake += Environment.NewLine;     
    }
}

byte[] handshakeText = Encoding.ASCII.GetBytes(handshake);
byte[] serverHandshakeResponse = new byte[handshakeText.Length];
Array.Copy(handshakeText, serverHandshakeResponse, handshakeText.Length);

ConnectionSocket.BeginSend(serverHandshakeResponse, 0, serverHandshakeResponse.Length, 0, HandshakeFinished, null);

The client side code looks like this.

ws = new WebSocket("ws://localhost:8181/test")
ws.onopen = WSonOpen;
ws.onmessage = WSonMessage;
ws.onclose = WSonClose;
ws.onerror = WSonError;

Sample Client Handshake

[0]: "GET /test HTTP/1.1"
[1]: "Upgrade: websocket"
[2]: "Connection: Upgrade"
[3]: "Host: localhost:8181"
[4]: "Origin: http://localhost:8080"
[5]: "Sec-WebSocket-Key: jKZrBlUEqqqstB+7wPES4A=="
[6]: "Sec-WebSocket-Version: 13"

Sample Server Response

[0]: "HTTP/1.1 101 Switching Protocols"
[1]: "Upgrade: websocket"
[2]: "Connection: Upgrade"
[3]: "Sec-WebSocket-Accept: mL2V6Yd+HNUHEKfUN6tf9s8EXjU="

Any help would be great. Thanks.

1

1 Answers

2
votes

One thing you did not post is what Environment.NewLine and HandshakeFinished are equal to.

The headers must comply with RFC 2616. In other words, each header line must end with CR+LF (carriage return + line feed or ASCII character 13 followed by ASCII character 10). The last header must be followed by an additional CR+LF in addition to the one indicating the end of the header line.

Also, although it's not causing you issues yet because your client code isn't setting it, you are also missing logic to handle sub-protocol selection. If the client sends a Sec-WebSocket-Protocol header, you must choose from one of the sub-protocols and return it in a Sec-WebSocket-Protocol response header.