我只是想让SignalR设置运行owin托管,我想通过JavaScript客户端连接。应该很容易吗?我能够快速设置并运行SignalR服务器并将客户端连接到服务器。但是,当在客户端上调用完成回调时,我尝试调用hubs Send方法,并在控制台中收到以下错误:
XMLHttpRequest无法加载http://localhost:8199/signalr/signalr/send?transport=serverSentEvents&clien ... AxBg6iaFwlK50s2DnurE& connectionData =%5B%7B%22name%22%3A%22testhub%22%7D%5D。 No' Access-Control-Allow-Origin'标头出现在请求的资源上。起源' http://localhost'因此不允许访问。响应的HTTP状态代码为500。
这是我的服务器端代码:
public static IAppBuilder UseService(this IAppBuilder app)
{
log4net.Config.XmlConfigurator.Configure();
app.UseService(NinjectConfig.CreateKernel);
app.UseLogging();
app.UseSignalr();
return app;
}
internal static IAppBuilder UseSignalr(this IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfig = new HubConfiguration {EnableDetailedErrors = true};
map.RunSignalR(hubConfig);
}
);
return app;
}
这是客户端:
var connection = $.hubConnection('http://localhost:8199/signalr');
var testHub = connection.createHubProxy('testHub');
testHub.on('addMessage', function(name){
console.log(name);
});
connection.start().done(function () {
testHub.invoke('send', 'testName');
}).fail(function (e) {
console.log('Failed to connect');
});
connection.error(function(error){
console.log(error);
});
为什么CORS请求适用于启动调用而不是后续的集线器方法调用?
更新: 在网络选项卡中,我可以看到有一个呼叫:http://localhost8199/signalr/negotiate - 此呼叫有效,CORS标头正按预期进行响应
然后调用:http://localhost:8199/signalr/connect并且该调用也具有正确的CORS标头并且有效。
然后打电话给:http://localhost:8199/signalr/start这里发生了同样好的事情。
最后调用:http://localhost:8199/signalr/send,这是失败的调用,每个失败消息都没有CORS头。
更新:
我也试过像这样设置我的客户端:
$.connection.hub.url = 'http://localhost:8199/signalr';
var proxy = $.connection.testHub;
proxy.client.addMessage = function(name){
console.log(name);
};
$.connection.hub.start()
.done(function () {
console.log($.connection.hub.id);
proxy.server.sendMessage()
.done(function(val){
console.log(val);
});
})
.fail(function (e) {
console.log('Failed to connect');
});
我对此工作没什么希望,因为我觉得问题是服务器端。但是我想更新我在这里尝试的内容。
答案 0 :(得分:2)
事实证明,我在浏览器中看到的错误是一个红色的鲱鱼。服务器端的CORS设置没有问题。我最终点击了chrome中控制台错误中的url:
XMLHttpRequest无法加载http://localhost:8199/signalr/signalr/send?transport=serverSentEvents&clien ... AxBg6iaFwlK50s2DnurE& connectionData =%5B%7B%22name%22%3A%22testhub%22%7D%5D。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许原点“http://localhost”访问。响应的HTTP状态代码为500。
这让我看到一个.Net黄色死亡屏幕,告诉我参数名称s不能为空,并且存在空引用异常。
最后,这是依赖性解析器的问题。我们在此项目中使用ninject内核进行依赖性解析。我不知道如果我的hub类有一个无参数的构造函数,SignalR会需要我通知它我的依赖解析器,但它确实需要这些信息。以下是我最终做的事情:
app.Map("/signalr", map =>
{
var resolver = new NinjectSignalRDependencyResolver(kernel);
GlobalHost.DependencyResolver = resolver;
map.UseCors(CorsOptions.AllowAll);
var hubConfig = new HubConfiguration { EnableDetailedErrors = true, EnableJSONP = true };
map.RunSignalR(hubConfig);
}
因此,要学习的经验是单击超链接,可能会出现根本错误。
答案 1 :(得分:1)
看一下这个:http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#crossdomain
请参阅说明,他们指出,根据您使用的浏览器,您可能需要修复不同的内容。
SignalR 1.0.1 Cross-domain request (CORS) with Chrome
SignalR IE9 Cross Domain request don't work
在启动方法中尝试EnableJSONP:
internal static IAppBuilder UseSignalr(this IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfig = new HubConfiguration {
EnableDetailedErrors = true,
EnableJSONP = true
};
map.RunSignalR(hubConfig);
};
return app;
}