SignalR:尝试连接时 webSockets 超时。可能的 CORS 问题
Posted
技术标签:
【中文标题】SignalR:尝试连接时 webSockets 超时。可能的 CORS 问题【英文标题】:SignalR: webSockets timed out when trying to connect. Possible CORS issue 【发布时间】:2015-03-29 06:43:23 【问题描述】:我正在尝试编写一个连接到具有信号器中心的现有网站的移动应用程序(角度)。我在网络服务器上配置了信号器:
// Branch the pipeline here for requests that start with "/signalr"
app.Map("/signalr", map =>
// Setup the CORS middleware to run before SignalR.
// By default this will allow all origins. You can
// configure the set of origins and/or http verbs by
// providing a cors options with a different policy.
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
// You can enable JSONP by uncommenting line below.
// JSONP requests are insecure but some older browsers (and some
// versions of IE) require JSONP to work cross domain
// EnableJSONP = true
EnableDetailedErrors = true
;
// Run the SignalR pipeline. We're not using MapSignalR
// since this branch already runs under the "/signalr"
// path.
map.RunSignalR(hubConfiguration);
);
服务器在现场运行:http://localhost:62115/
我有另一个客户端应用程序在 http://localhost:4434/ 上运行,我正在尝试使用来自 http://localhost:62115/ 的信号器集线器:
$.connection.hub.url = "http://localhost:62115/signalr/hubs";
var queueProxy = $.connection.queueHub;
$.connection.hub.logging = true;
$.connection.hub.start()
.done(function ()
alert('yes');
)
.fail(function (e)
alert(e);
);
但信号器无法连接。我收到错误无法成功初始化传输。以下是我的日志:
[16:19:58 GMT-0500 (Eastern Standard Time)] SignalR: Auto detected cross domain url.
jquery.signalR-2.1.1.js:81 [16:19:58 GMT-0500 (Eastern Standard Time)] SignalR: No hubs have been subscribed to. The client will not receive data from hubs. To fix, declare at least one client side function prior to connection start for each hub you wish to subscribe to.
jquery.signalR-2.1.1.js:81 [16:19:58 GMT-0500 (Eastern Standard Time)] SignalR: Negotiating with 'http://localhost:62115/signalr/hubs/negotiate?clientProtocol=1.4&connectionData=%5B%5D'.
jquery.signalR-2.1.1.js:81 [16:19:59 GMT-0500 (Eastern Standard Time)] SignalR: Connecting to websocket endpoint 'ws://localhost:62115/signalr/hubs/connect?transport=webSockets&clientProtocol=1.4&connectionToken=yNATl6%2FEQt710oI6ZGOV9%2F61Ry2SRjKQOgPDxKuXGSCYagKpbQKY5DOzRWdk1ggv6XaIm%2FJ2TUkkbmEkgCJyKHAKwy3ZweftP%2FYzRglLGe492Z4RDYY%2Btj8Aah3IhHIo&connectionData=%5B%5D&tid=2'.
jquery.signalR-2.1.1.js:81 [16:19:59 GMT-0500 (Eastern Standard Time)] SignalR: Websocket opened.
jquery.signalR-2.1.1.js:81 [16:20:04 GMT-0500 (Eastern Standard Time)] SignalR: webSockets timed out when trying to connect.
jquery.signalR-2.1.1.js:81 [16:20:04 GMT-0500 (Eastern Standard Time)] SignalR: Closing the Websocket.
jquery.signalR-2.1.1.js:81 [16:20:04 GMT-0500 (Eastern Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://localhost:62115/signalr/hubs/connect?transport=serverSentEvents&clie…AKwy3ZweftP%2FYzRglLGe492Z4RDYY%2Btj8Aah3IhHIo&connectionData=%5B%5D&tid=5'.
jquery.signalR-2.1.1.js:81 [16:20:04 GMT-0500 (Eastern Standard Time)] SignalR: EventSource connected.
jquery.signalR-2.1.1.js:81 [16:20:09 GMT-0500 (Eastern Standard Time)] SignalR: serverSentEvents timed out when trying to connect.
jquery.signalR-2.1.1.js:81 [16:20:09 GMT-0500 (Eastern Standard Time)] SignalR: EventSource calling close().
jquery.signalR-2.1.1.js:81 [16:20:09 GMT-0500 (Eastern Standard Time)] SignalR: Opening long polling request to 'http://localhost:62115/signalr/hubs/connect?transport=longPolling&clientPro…AKwy3ZweftP%2FYzRglLGe492Z4RDYY%2Btj8Aah3IhHIo&connectionData=%5B%5D&tid=6'.
jquery.signalR-2.1.1.js:81 [16:20:14 GMT-0500 (Eastern Standard Time)] SignalR: longPolling timed out when trying to connect.
jquery.signalR-2.1.1.js:81 [16:20:14 GMT-0500 (Eastern Standard Time)] SignalR: Aborted xhr request.
jquery.signalR-2.1.1.js:81 [16:20:24 GMT-0500 (Eastern Standard Time)] SignalR: Stopping connection.
jquery.signalR-2.1.1.js:81 [16:20:24 GMT-0500 (Eastern Standard Time)] SignalR: Fired ajax abort async = true.
【问题讨论】:
你能解决这个问题吗? 【参考方案1】:我也有同样的问题。协商步骤将列出所有传输方法,但随后它们会逐个超时(对我来说是 5 秒后)。甚至长轮询也被破坏了。
在我的例子中,我们使用 Redis 作为 SignalR 的缓存。我的本地副本运行良好,因为我们有一个仅将 Redis 缓存用于生产的条件。所以我认为这与它有关。
更新所有相关软件包为我解决了这个问题:
所有 Microsoft.AspNet.SignalR 包,包括客户端库 所有 Microsoft.Owin 包 StackExchange.Redis 所有 Autofac 包(因为 AutoFac 处理了被注入的 Redis 依赖项)【讨论】:
【参考方案2】:我遇到了类似的问题,并想在此处记录解决方案,以防其他人因 SignalR 连接问题而烦恼。失败有两个不同的奇怪原因:
时钟同步问题。 我正在发布到 Azure,SignalR 在暂存和生产环境中完美地工作。它突然无法在我的开发环境中连接。
我最近将我的系统时钟设置为比它在同一时区内的时间早了一小时。当我更正日期和时间时,SignalR 开始在我的本地机器上完美地运行所有协议。我在任何地方都找不到这方面的文档,但我知道 Azure 表、队列和 Blob 需要 15 分钟内的同步时钟。
Azure SignalR 背板服务总线问题。 我正在使用 Azure 服务总线背板在多个 Web 前端实例之间同步消息。我实际上有一个服务总线损坏(我不知道为什么,并在单独的帖子中提出了这个问题)。我知道这是服务总线,因为当我在 OWIN 启动中注释掉 GlobalHost.DependencyResolver.UseServiceBus 方法调用时,一切正常。当我将连接字符串切换到不同的服务总线时,它运行良好。但是 ONE BUS 会导致间歇性故障。
【讨论】:
我不明白为什么时钟会成为 SignalR 的问题。您的场景中的开发环境是客户端机器还是服务器? SignalR 与位于不同时区的队列紧密耦合的问题是什么?【参考方案3】:我遇到了类似的问题,有一段时间,当我将我的 nuget 包升级到有关跨域的最新版本时,这是一场艰苦的战斗。您能否尝试以下方法并告诉我这是否解决了您的问题?
public class Startup
public void Configuration(IAppBuilder app)
app.Map("/signalr", map =>
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration EnableJSONP = true );
);
public static class WebApiConfig
public static void Register(HttpConfiguration config)
// your client localhost
config.EnableCors(new EnableCorsAttribute(origins: "http://localhost:4434", headers: "*", methods: "*"));
// wack "/hubs"
$.connection.hub.url = "http://localhost:62115/signalr/
$.connection.hub.start( xdomain: true )
.done(function ()
console.log('Connected. connectionId : ' + $.connection.hub.id); )
.fail(function ()
console.log('Could not connect!');
);
最后一定要在您的客户端应用程序的<head>
中引用脚本。请注意,您明确引用了您的服务器正在运行的本地主机。
<script src="//localhost:62115/signalr/hubs"></script>
【讨论】:
不知道为什么投反对票 - 这个答案对我有用。我对其进行了调整,但启用 CORS 是解决方案,这在日志中并不明显。以上是关于SignalR:尝试连接时 webSockets 超时。可能的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
角度 SignalR 经常断开连接并显示错误状态代码 1006
centos nginx配置支持WebSocket(signalR)