允许SignalR与第三方WebSockets服务器集成需要什么?

时间:2014-10-31 18:13:53

标签: websocket signalr owin katana websocket4net

2部分问题

  1. 我是否正确实施此客户端?
  2. 如果我要实现自己的WebSockets服务器,那么我有哪些要求允许SignalR的传输协商过程识别WebSockets并能够将其用于通信?
  3. 请注意,我目前的技术限制涉及

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

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

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

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

    有些消息来源表示,这种限制仅适用于希望使用HTTP.sys的各方,而且自托管解决方案可以使用WebSockets: 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部分的代码是死胡同,我想我的下一个可行选择是使用适当的客户端(例如{{3})实现第三方Web套接字服务器(例如SuperWebSocket) })并公开套接字服务器以供SignalR使用。我希望答案是“没有。它只会工作”但是一旦我站起来并扩展我的CLR客户端来实现SignalR.Client.WebSocket4Net,需要让SignalR通信协商升级请求并开始运输在ws://?


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

1 个答案:

答案 0 :(得分:0)

第1部分

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

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

第2部分

您可能需要实施自己的ITransport来创建自己的WebSocketTransport,并在TransportManager中注册。{3}}。这是纯粹的推测,我从来没有尝试做过类似的事情:)只是,要小心你可以找到关于这个的小文档或经验......

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

我的0.02

为何选择SignalR?这是一种很快就不需要的填充物。 WebSockets是一种标准的,广泛支持的技术,在websocket-js的旧浏览器中易于填充。 SignalR为just good for applications that broadcast general data(查看限制部分)。我编写并维护了WebSocket library named WebSocketListener,您可能想尝试一下:)(虽然它没有客户端)。我建议您在选择一个库之前测试几个库的性能和可伸缩性;)