首页 > 解决方案 > WSS 支持 C# .exe 通过 https 工作

问题描述

我有.net .exe,它监听网络套接字。它在 http 上完美运行。当我的发件人通过 https 转移到 WSS 时,我的 .exe 无法解密传入的请求。我的客户端收到字节数组,但是当我尝试将其解密为 UTF 编码时,它无法通过正确解密Encoding.GetEncoding("ISO-8859-1");

代码:

public void ReadCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the state object
        // and the handler socket
        // from the asynchronous state object.
        var state = (StateObject)ar.AsyncState;
        // Read data from the client socket. 
        var bytesRead = _socket.EndReceive(ar);

        // Below code doesn't decrypt correctly for wss
        // but works correctly for ws
        Utils.Encoding.GetString(state.Buffer, 0, bytesRead);

标签: c#httpswss

解决方案


在您现有的代码中,您在套接字层谈论原始字节,直接从SocketEncoding. 这对于未加密的数据来说很好,因为数据实际上是相同的字节(尽管......只有握手的第一部分是文本;在 HTTP 标头之后,您应该处理帧解析器,理想情况下,所以靠近Encoding这里有点危险;上下文:我也直接从该Socket层编写了一个成功的、高吞吐量的 web-socket 服务器)。

但是:当你在中间有任何字节转换要做时,这并不是那么简单——这里就是 TLS(如果这也是压缩转换,你也会遇到同样的问题)。

很简单:需要有人来处理实际的 TLS 工作。如果您决心自己处理细节,那么您最好的选择可能是包装:

Socket<===> NetworkStream<===> SslStream<===> (你的代码)

这意味着您将针对StreamAPI 进行编码,而不是SocketAPI(可能AuthenticateAsServer()在初始化服务器流时使用)。为避免有两个代码库,您可以只使用:

Socket<===> NetworkStream<===>(你的代码)

ws层。但是,坦率地说,IMO 最好让框架和库担心这一点 - 特别是如果您使用 .NET Core:您可以使用 Kestrel 设置支持 TLS 的 Web 服务器,您的代码基本上只是:

public void Configure(IApplicationBuilder app)
{
    app.UseWebSockets(new WebSocketOptions()
    {
        // set KeepAliveInterval / ReceiveBufferSize / etc
    });
    app.Run(ctx =>
    {
        if (ctx.WebSockets.IsWebSocketRequest)
        {
            return RunClientAsync(ctx);
        }
        else { /* whatever you want to do when not WS/WSS */ }
    });
}
private async Task RunClientAsync(HttpContext context)
{
    var socket = await context.WebSockets.AcceptWebSocketAsync();
    // TODO: all your read/write logic using the WebSocket API
}

这种方法在 .NET Core 3.1 上的扩展性比在 .NET Framework 上要好得多(检查我的状态页面);我目前在 9 个节点上运行约 518,000 个并发 Web 套接字连接(因为我恰好有 9 个节点可用),CPU 几乎为 0%,每个节点 5 个端口(以避免临时端口耗尽)每个端口每个端口约 11,500 个连接节点。我们迁移了自定义Socket级别的代码以使用WebSocket.NET Core 3.1 的 API,因为这些改进意味着我们不再需要维护自己的代码来处理 web-socket 协议的细微差别。


推荐阅读