除了我在版本13(RFS 6455)中遇到问题外,我还有在另一篇文章中问到的相同问题。是否有人使用此版本成功实现了web套接字服务器?我试过了我能找到的所有其他建议,但都没有奏效。
相关岗位:web套接字服务器:从未调用web套接字上的onopen函数。
客户端是Chrome 16上的javascript。服务器是一个C#控制台应用程序。
我的服务器能够接收客户端握手并成功发送响应,但客户端上没有触发onopen/onmessage事件。
对于大多数在线用户来说,问题似乎在于握手消息本身,但我能找到的所有例子都是-75或-76版本的。
我遵循此处的说明:https://www.rfc-editor.org/rfc/rfc6455#page-39
在这里,我初始化服务器握手响应。
handshake = "HTTP/1.1 101 Switching Protocols" + Environment.NewLine;
handshake += "Upgrade: websocket" + Environment.NewLine;
handshake += "Connection: Upgrade" + Environment.NewLine;
handshake += "Sec-WebSocket-Accept: ";
这就是我接收客户端握手消息、生成响应密钥并将其发送回的地方。
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);
客户端代码如下所示。
ws = new WebSocket("ws://localhost:8181/test")
ws.onopen = WSonOpen;
ws.onmessage = WSonMessage;
ws.onclose = WSonClose;
ws.onerror = WSonError;
客户端握手示例
[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"
示例服务器响应
[0]: "HTTP/1.1 101 Switching Protocols"
[1]: "Upgrade: websocket"
[2]: "Connection: Upgrade"
[3]: "Sec-WebSocket-Accept: mL2V6Yd+HNUHEKfUN6tf9s8EXjU="
任何帮助都会很棒。谢谢
您没有发布的一件事是Environment.NewLine和HandshakeFinished等于什么。
标头必须符合RFC 2616。换句话说,每个标题行必须以CR+LF结尾(回车+换行或ASCII字符13后跟ASCII字符10)。除了指示标题行结束的CR+LF之外,最后一个标题后面还必须跟一个额外的CR+RF。
此外,尽管它还没有给您带来问题,因为您的客户端代码没有设置它,但您也缺少处理子协议选择的逻辑。如果客户端发送Sec-WebSocket Protocol标头,则必须从其中一个子协议中进行选择,并将其返回到Sec-Webocket Protocol响应标头中。