【问题标题】:What is required to allow SignalR to integrate with a third party WebSockets server?允许 SignalR 与第三方 WebSockets 服务器集成需要什么?
【发布时间】:2014-12-28 03:31:33
【问题描述】:

2 部分问题

  1. 我是否正确实现了这个客户端?
  2. 如果我要实现自己的 WebSockets 服务器,我有什么要求让 SignalR 的传输协商过程能够识别 WebSockets 并能够使用它进行通信?

请注意,我目前的技术限制涉及

  • Windows 7,
  • 框架 4.5,
  • Owin 自托管(控制台)SignalR 服务器,
  • Owin 自托管(控制台).NET 客户端,
  • Web 客户端 (Javascript)

第 1 部分:尝试使用 System.Net.WebSockets.ClientWebSocket 客户端实现 Katana 示例

所以我正在构建一个自托管的 SignalR 进程,我注意到在我的提琴手流量中我的连接正在使用 LongPolling,而我希望它使用 WebSockets,所以我开始研究什么将需要使 WebSockets 可用。

一些快速研究导致了混合信息: 一些消息来源表明 WebSockets 仅在 Windows 8 和 IIS 8 上可用,并且 WebSockets 实现已集成在操作系统级别。

一些消息来源指出,该限制仅适用于希望使用 HTTP.sys 的各方,并且自托管解决方案可以利用 WebSocket: Katana Sample WebSocket Server Katana Sample WebSocket Client

所以我着手实现 Katana 示例 - 我有一个 SignalR 服务器,我想通过 WebSockets、一个 .NET 客户端和一个 Web 客户端将它公开到我的 SignalR 服务器中,当我尝试执行以下代码时在我的 .NET 客户端中(截断当前不相关的客户端代码部分):

static void Main(string[] args)
        {
            Console.WriteLine("╔════════════════════════════════════════════════════════════════════════════╗");
            Console.WriteLine("╠»»»-                     Starting Service.Host-                   «««╣");

            Console.WriteLine("║-- Connecting to Client Messaging Hub-- ");
            Console.WriteLine("║.....Attempting to upgrade to WebSockets ");

            //UseDefaultConnectionParameters();
            Connect("ws://localhost:8080");

            Console.WriteLine(String.Format("║-->Connection Established [{0}]", @"ws://localhost:8080"));
            Console.WriteLine("╠»»»                   Service.Host now  started                   «««╣");
            Console.WriteLine("╚════════════════════════════════════════════════════════════════════════════╝");
            Console.ReadLine();

        }
        private static async Task Connect(string uri)
        {
            ClientWebSocket websocket = null;
            try
            {
                websocket = new ClientWebSocket();//<= Throws exception
                await websocket.ConnectAsync(new Uri(uri), CancellationToken.None);
                await Task.WhenAll(Receive(websocket), Send(websocket));
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception: {0}", ex);
            }
            finally
            {
                if (websocket != null)
                    websocket.Dispose();
                Console.WriteLine();

                lock(master)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("WebSocket closed.");
                    Console.ResetColor();
                }
            }


        }

我的 Connect() 函数内的行

ClientWebSocket websocket = new System.Net.WebSockets.ClientWebSocket();

抛出

Exception: System.PlatformNotSupportedException: The WebSocket protocol is not s
upported on this platform.
   at System.Net.WebSockets.ClientWebSocket..ctor().  

(我的 CLR 客户端库面向 .NET Framework 4.5)

这是否遇到了一个硬限制,即您实际上无法在没有 Windows 8 的情况下从 System.Net.WebSockets 命名空间创建 WebSocket 客户端?

第 2 部分:调查第三方 WebSocket 服务器/客户端的影响

假设第 1 部分中的代码是死胡同,我想我的下一个可行选择是使用适当的客户端(例如 SignalR.Client.WebSocket4Net)实现第三方 Web 套接字服务器(例如 SuperWebSocket)并公开SignalR 使用的套接字服务器。我希望答案是“什么都没有。它会正常工作”但是一旦我站起来 SuperWebSocket 并扩展我的 CLR 客户端以实现 SignalR.Client.WebSocket4Net,SignalR 通信需要什么来协商升级请求并开始传输超过 ws:// ?


任何人都可以就这两条路径中的任何一条提供任何指导吗?如果我选择了错误的路线,我预见到会浪费很多时间。

【问题讨论】:

    标签: websocket signalr owin katana websocket4net


    【解决方案1】:

    第 1 部分

    在 Windows 8 和 2012 中发布的新版本 http.sys 负责将常规 HTTP 请求转换为持久的、二进制的、双向的 TCP 连接,即 WebSocket。这就是允许 IIS 在建立 websocket 连接时切换协议的原因。

    为什么 ClientWebSockets 不能在 Windows 7 上运行?好吧,这根本没有意义,但服务器和客户端之间可能存在一些共享功能,这就是它在“旧”操作系统中被 PlatformNotSupportedException 阻止的原因。

    第 2 部分

    您可能需要实现自己的ITransport 来创建自己的WebSocketTransport,并将其注册到TransportManager。这纯粹是猜测,我从未尝试过这样做 :) 只是,请注意您可以找到的关于此的少量文档或经验...

    但是问题来了,如果您的客户端切换到另一个传输,它将失败!因为操作系统无法在同一个端口上侦听长轮询和 websocket,所以对 WebSocket 组件的常规 HTTP 请求将不会产生任何影响。这就是 http.sys 在其新版本中所做的技巧,监听 HTTP 常规请求,如果需要,仍然可以在 websocket 上打开其中一个。

    我的 0.02

    为什么选择 SignalR?这是一个不会很快被需要的 polyfill。 WebSockets 是一种标准的、被广泛支持的技术,并且很容易在旧浏览器中使用 websocket-js 进行 polyfill。 SignalR 是just good for applications that broadcast general data(检查限制部分)。我编写并维护了一个WebSocket library named WebSocketListener,您可能想尝试一下:)(虽然它没有客户端)。我建议您在选择一个库之前测试几个库的性能和可扩展性;)

    【讨论】:

      猜你喜欢
      • 2019-01-02
      • 2014-10-09
      • 2018-06-12
      • 1970-01-01
      • 2012-02-22
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 2013-02-06
      相关资源
      最近更新 更多