建立一个简单的websocket握手

时间:2013-11-18 07:40:21

标签: c# asp.net websocket

客户端:

 <script type="text/javascript">
        var socket = new WebSocket('ws://localhost:8183/websession');
        socket.onopen = function () {
            alert('handshake successfully established. May send data now...');
        };
        socket.onclose = function () {
            alert('connection closed');
        };
</script>

服务器:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Net.Sockets;
 using System.Net;
 using System.IO;


class Program
{
    static void Main(string[] args)
    {
        var listener = new TcpListener(IPAddress.Loopback, 8183);
        listener.Start();
        using (var client = listener.AcceptTcpClient())
        using (var stream = client.GetStream())
        using (var reader = new StreamReader(stream))
        using (var writer = new StreamWriter(stream))
        {
            writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake");
            writer.WriteLine("Upgrade: WebSocket");
            writer.WriteLine("Connection: Upgrade");
            writer.WriteLine("WebSocket-Origin: http://localhost:8092");
            writer.WriteLine("WebSocket-Location: ws://localhost:8183/websession");
            writer.WriteLine("");
        }
        listener.Stop();
    }
}

问题是连接永远不会建立,onopen函数永远不会被调用可能是什么问题?

1 个答案:

答案 0 :(得分:3)

首先,您的“服务器”似乎正在发送握手的“客户端”部分。其次,StreamReaderStreamWriter 对您没有多大帮助 ;坦率地说,你只需使用Stream即可。

现在,实际握手很复杂;客户端和服务器都需要向他人证明,而不是实际谈论Web套接字,而不是HTTP。确切的性质取决于您尝试支持的协议版本(或多个协议),但服务器需要根据客户端的标头执行数学计算发送;服务器在标头中发送回答,并检查它们是否使用相同的语言。请注意,这是安全步骤:它是一个完整性保护步骤。这在specification中都有描述,但是一个示例请求/响应对(来自该文档):

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

之后,它从HTTP下降到web-socket协议,这是二进制的,与HTTP无关。有关信息,Sec-WebSocket-Accept是数学计算的结果,基于客户的Sec-WebSocket-Key

您需要的下一部分代码是帧支持。再次 - 参见规范。另请注意,此规范仅版本13 。如果您想支持所有客户端,您可能还需要检查旧规范(除了原始原始协议之外,还有一些微妙的调整,这是完全不同的,并且需要完全不同的代码)。

在编写所有这些之前,您可能想要了解一个预先存在的库是否更实用。 Windows 8(和类似版本的服务器)在HTTP.SYS中包含web-socket supprt,完全支持.NET。