客户端:
<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函数永远不会被调用可能是什么问题?
答案 0 :(得分:3)
首先,您的“服务器”似乎正在发送握手的“客户端”部分。其次,StreamReader
和StreamWriter
对您没有多大帮助 ;坦率地说,你只需使用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。