c# - 建立一个简单的 websocket 握手

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

最佳答案

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

现在,实际的握手很复杂;客户端和服务器都需要相互证明,而不是他们实际上在谈论网络套接字,而不是 HTTP。这的确切性质取决于您尝试支持的协议(protocol)版本(或多个协议(protocol)),但是服务器需要根据客户端的 header 执行数学计算 发送;服务器在它的 header 中发回答案,这会检查它们是否使用相同的语言。请注意,这不是安全步骤:它是健全保护步骤。所有这些都在 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 协议(protocol),这是二进制的,与 HTTP 无关。对于信息,Sec-WebSocket-Accept 是根据客户端的 Sec-WebSocket-Key 进行数学计算的结果。

您需要的下一段代码是框架支持。再次 - 请参阅规范。另请记住,此规范只是第 13 版。如果你想支持所有客户端,你可能还需要检查旧规范(有一些细微的调整,除了 original original 协议(protocol),它完全不同,需要完全不同的代码)。

在编写所有这些内容之前,您可能想要研究一个预先存在的库是否更实用。 Windows 8(和类似版本的服务器)在 HTTP.SYS 中直接包含 Web 套接字支持,并在 .NET 中提供全面支持。

关于c# - 建立一个简单的 websocket 握手,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20042477/

相关文章:

c# - C# try-finally CERs 会在迭代器中中断吗?

c# - .NET Core Cronos Cron 表达式未正确解析

asp.net - IIS7 : Sharing Sessions Between Applications With State Server

python - aiohttp - 如何查看 websocket 消息缓冲区?

sockets - Web套接字: Is it bad to always use SSL when making an online game?

c# - 在 SharePoint 2010 中启用 session 状态?

c# - DateTimeFormatInfo.MonthDayPattern 在 Windows Server 2012 中已更改 - 如何将其恢复?

c# - Facebook C# SDK 获取用户accessToken

asp.net - 如何在 Web App 和 Windows 窗体应用程序之间进行交互

Jmeter 的 WebSocket 插件