SignalR 客户端连接错误(UWP 和 JavaScript 客户端)

本文关键字:客户端 JavaScript UWP 连接 错误 SignalR | 更新日期: 2023-09-27 18:33:30

我两者都有,一个简单的UWP应用程序在Visual Studio的本地机器上运行,一个简单的AngularJS SPA。我还有一个基于 OWIN 的自托管服务器在 Service Fabric 群集中运行。服务器使用 Web API 和 signalR。

当我在本地计算机上托管 Service Fabric 群集时,UWP 应用和角度应用可以打开与服务器上的 signalR 中心的连接。当我在 Azure 上托管 Service Fabric 群集时,客户端无法连接到 signalR 中心。我得到:failed: Error during WebSocket handshake: Unexpected response code: 400

启动类中的服务器端代码:

        public void Configuration(IAppBuilder appBuilder)
        {
            HttpConfiguration httpConfig = this.ConfigureWebApi();
            FileServerOptions fileServerOptions = this.ConfigureFileSystem(appBuilder);                           appBuilder.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            appBuilder.UseWebApi(this.ConfigureWebApi());
            appBuilder.UseFileServer(fileServerOptions);
            appBuilder.MapSignalR();

服务器上的 SignalR 中心类:

    public class SensorDataHub : Hub
    {
        public void UpdateSensorData(SensorDataModel data)
        {
            Clients.All.updateChartData(data);
        }            
    }

UWP 代码:

        private async void OpenSignalRConnection()
        {    
            //this.SensorDataHubCon = new HubConnection("http://localhost:80/");
            this.SensorDataHubCon = new HubConnection("http://rivutec.westeurope.cloudapp.azure.com/");
            this.SensorDataHubProxy = this.SensorDataHubCon.CreateHubProxy("SensorDataHub");
            await this.SensorDataHubCon.Start();
        }

AngularJS代码:

            var connection = $.hubConnection("http://localhost:80/");
            //var connection = $.hubConnection("http://test.server.com/");
            var proxy = connection.createHubProxy("SensorDataHub");
            proxy.on("updateChartData", function (data) {
                console.log(data.current);
            });
            connection.start()
                .done(function () { console.log('Now connected, connection ID=' + $.connection.hub.id); })
                .fail(function () { console.log('Could not Connect!'); });

正如我上面写的,UWP 客户端和角度客户端可以打开与localhost的中心连接。

但是,当我尝试将 UWP 客户端连接到云上发布的 signalR 中心时,出现Bad Request错误:

Microsoft.AspNet.SignalR.Client.HttpClientException was unhandled by user code
  HResult=-2146233088
  Message=StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Server: Microsoft-HTTPAPI/2.0
  Transfer-Encoding: chunked
  Date: Sun, 07 Feb 2016 13:59:09 GMT
  X-Content-Type-Options: nosniff
}
  Source=Microsoft.AspNet.SignalR.Client
  StackTrace:
       at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.<>c__DisplayClass6.<Post>b__5(HttpResponseMessage responseMessage)
       at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.<Then>b__17(Task`1 t)
       at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.<RunTask>b__41(Task`1 t)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
       at SerialSample.MainPage.<OpenSignalRConnection>d__9.MoveNext()
  InnerException: 

信号跟踪说:

13:59:02.3510728 - ac120389-8e08-4690-8e38-4538b602260e - SSE: GET http://test.server.com/signalr/connect?clientProtocol=1.4&transport=serverSentEvents&connectionData=[{"Name":"SensorDataHub"}]&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAADhW4uMBq5ClXKT3X5UGNGLq3YzdxgD4blCiGSRFL8b8AAAAAAOgAAAAAIAACAAAABGZnghjduUUMHt3QMlhMxIRsajzvG0kWW4ECTpnppl4DAAAAALVIQ46T3%2BdnUpON%2FrpgZO8idns8YNkRrK9lMMxKQz7xYTgM8ViIcxeMNx7%2FamQsRAAAAA5KtFAgG0yKxNVlzAfGNc0cHP8NXxEmaK1i%2Blf52xb7SNmpz%2B5O%2BJxZmVz71Z3pdHV4Z1LyGJixJsRxnQEJOtfA%3D%3D&noCache=28c5a100-2796-4287-958b-0c2ccbd1e91a
The thread 0x4b04 has exited with code 0 (0x0).
13:59:07.3914634 - ac120389-8e08-4690-8e38-4538b602260e - Auto: Failed to connect to using transport serverSentEvents. System.TimeoutException: Transport timed out trying to connect
13:59:07.3994644 - ac120389-8e08-4690-8e38-4538b602260e - LP Connect: http://test.server.com/signalr/connect?clientProtocol=1.4&transport=longPolling&connectionData=[{"Name":"SensorDataHub"}]&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAADhW4uMBq5ClXKT3X5UGNGLq3YzdxgD4blCiGSRFL8b8AAAAAAOgAAAAAIAACAAAABGZnghjduUUMHt3QMlhMxIRsajzvG0kWW4ECTpnppl4DAAAAALVIQ46T3%2BdnUpON%2FrpgZO8idns8YNkRrK9lMMxKQz7xYTgM8ViIcxeMNx7%2FamQsRAAAAA5KtFAgG0yKxNVlzAfGNc0cHP8NXxEmaK1i%2Blf52xb7SNmpz%2B5O%2BJxZmVz71Z3pdHV4Z1LyGJixJsRxnQEJOtfA%3D%3D&noCache=78a5c718-439d-440f-9b68-c0658135209f
'SerialSample.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:'Users'...'Downloads'samples-develop'samples-develop'SerialSample'CS'bin'x86'Debug'AppX'System.Net.Requests.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
13:59:07.5434999 - ac120389-8e08-4690-8e38-4538b602260e - Auto: Failed to connect to using transport longPolling. Microsoft.AspNet.SignalR.Client.HttpClientException: StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Server: Microsoft-HTTPAPI/2.0
  Transfer-Encoding: chunked
  Date: Sun, 07 Feb 2016 13:59:09 GMT
  X-Content-Type-Options: nosniff
}
   at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.<>c__DisplayClass6.<Post>b__5(HttpResponseMessage responseMessage)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.<Then>b__17(Task`1 t)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.<RunTask>b__41(Task`1 t)
13:59:07.5755002 - ac120389-8e08-4690-8e38-4538b602260e - OnError(Microsoft.AspNet.SignalR.Client.HttpClientException: StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Server: Microsoft-HTTPAPI/2.0
  Transfer-Encoding: chunked
  Date: Sun, 07 Feb 2016 13:59:09 GMT
  X-Content-Type-Options: nosniff
}
   at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.<>c__DisplayClass6.<Post>b__5(HttpResponseMessage responseMessage)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.<Then>b__17(Task`1 t)
   at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.<RunTask>b__41(Task`1 t))
13:59:07.6070094 - ac120389-8e08-4690-8e38-4538b602260e - Disconnected
13:59:07.6100082 - ac120389-8e08-4690-8e38-4538b602260e - Transport.Dispose(ac120389-8e08-4690-8e38-4538b602260e)
13:59:07.6135102 - ac120389-8e08-4690-8e38-4538b602260e - Closed
Exception thrown: 'Microsoft.AspNet.SignalR.Client.HttpClientException' in mscorlib.ni.dll

角度客户端错误说:

[21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Client subscribed to hub 'sensordatahub'.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Negotiating with 'http://test.server.com//signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D'.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: webSockets transport starting.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Connecting to websocket endpoint 'ws://test.server.com/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAAC8DLAeriEnbunGPma3%2F%2FChRl1tm6XCfCHDLEEBfpjszgAAAAAOgAAAAAIAACAAAACANAtQqijBRvg4FloVq0JnylH9%2Bm6j5coY3Yr0yP60mzAAAAD4qw2VdYIQJ3CYQPcPbr2LhyfPhhJtPPgJ33FZuPLQh8owubvHYD5jhRsXdMxHfitAAAAAJX0cLVthvatbmOa%2BNbRSt%2B8CnVJ%2FQ9ks1x%2Bzlk2wA8iF6OVU03wXaNK17FXK2%2BlFmU6hIk8euqJVXeZMz7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D&tid=4'.
jquery.signalR.min.js:8 WebSocket connection to 'ws://test.server.com/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAAC8DLAeriEnbunGPma3%2F%2FChRl1tm6XCfCHDLEEBfpjszgAAAAAOgAAAAAIAACAAAACANAtQqijBRvg4FloVq0JnylH9%2Bm6j5coY3Yr0yP60mzAAAAD4qw2VdYIQJ3CYQPcPbr2LhyfPhhJtPPgJ33FZuPLQh8owubvHYD5jhRsXdMxHfitAAAAAJX0cLVthvatbmOa%2BNbRSt%2B8CnVJ%2FQ9ks1x%2Bzlk2wA8iF6OVU03wXaNK17FXK2%2BlFmU6hIk8euqJVXeZMz7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D&tid=4' failed: Error during WebSocket handshake: Unexpected response code: 400
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Websocket closed.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Closing the Websocket.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: webSockets transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: serverSentEvents transport starting.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Attempting to connect to SSE endpoint 'http://test.server.com/signalr/connect?transport=serv…nw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D&tid=6'.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: serverSentEvents transport timed out when trying to connect.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: EventSource calling close().
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: serverSentEvents transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: foreverFrame transport starting.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Forever Frame is not supported by SignalR on browsers with SSE support.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: foreverFrame transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: longPolling transport starting.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Opening long polling request to 'http://test.server.com/signalr/connect?transport=long…z7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D'.
jquery.min.js:4 POST http://test.server.com/signalr/connect?transport=long…z7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D 400 (Bad Request)l.cors.b.crossDomain.send @ jquery.min.js:4n.extend.ajax @ jquery.min.js:4r.transports._logic.ajax @ jquery.signalR.min.js:8e @ jquery.signalR.min.js:8(anonymous function) @ jquery.signalR.min.js:8
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: longPolling transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Fallback transports exhausted.
signalRHubService.js:13 Could not Connect!
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Stopping connection.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Fired ajax abort async = true.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: LongPolling failed to connect.
jquery.min.js:4 POST http://test.server.com//signalr/abort?transport=longP…z7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D 400 (Bad Request)l.cors.b.crossDomain.send @ jquery.min.js:4n.extend.ajax @ jquery.min.js:4r.transports._logic.ajax @ jquery.signalR.min.js:8r.transports._logic.ajaxAbort @ jquery.signalR.min.js:8r.transports.longPolling.abort @ jquery.signalR.min.js:8r.fn.r.stop @ jquery.signalR.min.js:8a.state.r.connectionState.connecting.d @ jquery.signalR.min.js:8v @ jquery.signalR.min.js:8h.transportFailed @ jquery.signalR.min.js:8(anonymous function) @ jquery.signalR.min.js:8y @ jquery.signalR.min.js:8s.pollXhr.i.ajax.error @ jquery.signalR.min.js:8i @ jquery.min.js:2j.fireWith @ jquery.min.js:2z @ jquery.min.js:4(anonymous function) @ jquery.min.js:4

我越来越failed: Error during WebSocket handshake: Unexpected response code: 400.为什么我可以在本地主机上连接,但不能在云上连接?

SignalR 客户端连接错误(UWP 和 JavaScript 客户端)

没有看到更多代码,这只是一个 WAG,但是...

基于这是一个"错误请求"错误并且日志说它在所有传输类型上都超时的事实,我的直觉告诉我,在您的本地计算机上,

  • 为 OWIN 自主机配置 URI 时,会告知它绑定到 localhost:80。
  • 当 Service Fabric 本地群集启动并运行时有状态/更少服务(或者我想你可以用演员来做(它实例化 OWIN 自主机
  • OWIN 绑定到本地主机:80
  • ,对本地主机:80 的请求在那里正确路由
  • 有温暖的绒毛。

    但是,将群集向上移动到 Azure 时:

  • 你想要更改 OWIN URI 地址,因为本地主机不再合适,

  • 所以你选择了"test.server.com",或者它实际上是什么。
  • 不过现在,群集不在一台计算机上,而是在 Azure 中。无论您要使用什么绑定,都可能无效。
  • 这意味着,OWIN 主机可能正在侦听"test.server.com"请求,但没有请求来,因为没有 DNS 将"test.server.com"指向托管服务(托管 OWIN 自托管(的服务结构计算机。

    我读过的一些文档指出,Service Fabric 框架有自己的名称服务器,可将 Service Fabric 引用解析为实际的计算机地址,这就是为什么您使用"fabric:"协议引用 Service Fabric 服务,并让路由魔术在幕后发生。 因此,同样的限制意味着你不能在不使用中介的情况下直接公开 Service Fabric 服务的 HTTP 终结点(有关详细信息,请参阅此 MSDN 文章(将限制你自托管和绑定到外部客户端可以使用的 uri 的能力。

本文介绍如何在 Azure 辅助角色中使用 OWIN 自承载 Web API,但该示例仅限于使用本地模拟器,并且似乎没有解决分配给终结点的 IP 地址可能会在云中更改的事实,因此很难在客户端上可靠地寻址。

如果尝试将 SignalR 中心移动到 Service Fabric,因为希望能够利用 Service Fabric 的可伸缩性,请查看此处。当前建议/支持的横向扩展 SignalR 的路径(看起来最适合你所拥有的路径(将使用 Web 角色和 Azure 服务总线,如下所示。