我有两个,一个在Visual Studio中的本地机器上运行的简单UWP应用程序和一个简单的AngularJS SPA。我还有一个在Service Fabric Cluster中运行的基于OWIN的自托管服务器。服务器使用web api和signalR。
当我在本地计算机上托管Service Fabric Cluster时,UWP应用程序和角度应用程序可以打开与服务器上signalR集线器的连接。当我在Azure上托管Service Fabric Cluster时,客户端无法连接到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:
signalR追踪说:
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
。为什么我可以在localhost上连接,但不能在云上连接?
答案 0 :(得分:0)
如果没有看到更多代码,这只是一个WAG,但是......
基于这是一个“错误请求”错误并且日志显示它在所有传输类型上超时的事实,我的直觉告诉我在您的本地计算机上,
有温暖的模糊。
但是,将群集移动到Azure时:
您想要更改OWIN uri地址,因为localhost不再合适,
意思是,您的OWIN主机可能正在侦听'test.server.com'请求,但没有一个是因为没有DNS将'test.server.com'指向托管该服务的服务结构机器服务(托管OWIN自托管)。
我读到的一些文档指出,服务结构框架有自己的名称服务器,可以解析服务结构对实际机器地址的引用,这就是为什么你使用'fabric:'协议引用服务结构服务并让路由魔术在幕后发生。因此,相同的限制意味着您无法在不使用中介的情况下直接公开Service Fabric服务的HTTP端点(详情请参阅此MSDN article),这将限制您自我托管和绑定到uri的能力外部客户可以使用。
This article讨论了如何使用OWIN在Azure Worker角色中自托管Web API,但该示例仅限于使用本地模拟器,并且似乎没有解决分配给端点可以并且会在云中发生变化,这使得很难在客户端上可靠地解决问题。
如果您尝试将SignalR集线器移动到Service Fabric,因为您希望能够利用Service Fabric的可扩展性check here。当前推荐/支持的扩展SignalR的路径看起来最适合您所拥有的内容,将使用Web角色和Azure Service Bus作为shown here。