【问题标题】:Establishing a simple websocket handshake建立一个简单的 websocket 握手
【发布时间】:2013-11-18 07:40:20
【问题描述】:

客户:

 <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 函数可能是什么问题?

【问题讨论】:

  • 你有什么建议?我应该用什么?
  • @Damien_The_Unbeliever 这不是真的;网络套接字绝对是 TCP 套接字,您绝对可以通过TcpListener 实现网络套接字。不过,我个人会使用裸Socket / Stream。我知道这一点因为我编写了我们在 Stack Exchange 使用的 web-socket 服务器。这……有点忙。
  • 所以@MarcGravell你能告诉我为什么我的代码不起作用吗?
  • @Sora 正在处理它;p 正在回答中

标签: c# asp.net websocket


【解决方案1】:

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

现在,实际的握手很复杂;客户端和服务器都需要相互证明,而不是它们实际上是在谈论 web-sockets,而不是 HTTP。这的确切性质取决于您尝试支持的协议版本(或多个协议),但 服务器 需要根据 客户端的标头执行数学计算 发送;服务器在 its 标头中发送回答案,并检查它们是否使用相同的语言。请注意,这不是安全步骤:这是一个健全的保护步骤。这在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。如果您想支持所有客户端,您可能还需要检查旧规范(有一些细微的调整,除了 original original 协议,它完全不同,需要完全不同的代码)。

在编写所有这些之前,您可能想研究一下现有的库是否更实用。 Windows 8(和类似版本的服务器)在 HTTP.SYS 中直接支持 web-socket,在 .NET 中完全支持。

【讨论】:

  • 我阅读了您的回复并看到了规范链接,但我仍然无法弄清楚我应该如何修复我的代码以完成连接
  • @Sora 通过实现 web-sockets 协议并发送正确的响应标头;然后实现框架;这不是微不足道的代码。我无法估计“多长时间”,因为 a:我不知道您对二进制协议有多熟悉,并且 b:我不知道该服务器需要支持多少客户端(这可能会改变设计显著地)。但在最少这将是一天的可靠编码。因此,我不能在此处的回复中真正包含所有这些内容。除了说:请考虑使用现有的库,除非你真的需要手动完成。
  • 非常感谢您的时间和辛勤工作,感谢您的回复,我将通过阅读有关 websockets 以及如何实现它们的更多信息来考虑您所说的
猜你喜欢
  • 2021-08-10
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多