asp.net-web-api – 交叉原始SignalR连接在协商后停止

前端之家收集整理的这篇文章主要介绍了asp.net-web-api – 交叉原始SignalR连接在协商后停止前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个MVC 5应用程序提供视图,一个Web API 2应用程序作为服务层(.NET 4.5). Web API应用程序使用SignalR 2.1.2在处理POST到服务API时返回进度.这两个部署到不同的域,因此我根据 asp.net教程文章设置了跨源支持.
  1. [assembly: OwinStartup(typeof (Startup))]
  2. namespace MyApp.Service
  3. {
  4. public class Startup
  5. {
  6. public void Configuration(IAppBuilder app)
  7. {
  8. app.Map("/signalr",map =>
  9. {
  10. //worry about locking it down to specific origin later
  11. map.UseCors(CorsOptions.AllowAll);
  12. map.RunSignalR(new HubConfiguration());
  13. });
  14. //now start the WebAPI app
  15. GlobalConfiguration.Configure(WebApiConfig.Register);
  16. }
  17. }
  18. }

WebApiConfig.cs还包含自己的CORS声明.

  1. namespace MyApp.Service
  2. {
  3. public static class WebApiConfig
  4. {
  5. public static void Register(HttpConfiguration config)
  6. {
  7. //controller invocations will come from the MVC project which is deployed to a
  8. //different domain,so must enable cross origin resource sharing
  9. config.EnableCors();
  10. // Web API routes
  11. config.MapHttpAttributeRoutes();
  12.  
  13. //Snip other controller dependency initialisation
  14. }
  15. }
  16. }

我已经定义了一个没有服务器端API的简单集线器类(它只允许服务器推送到客户端,而不是客户端调用).

  1. namespace MyApp.Service.Hubs
  2. {
  3. [HubName("testresult")]
  4. public class TestResultHub : Hub
  5. {
  6. }
  7. }

由于我要跨域并且集线器没有公开任何服务器端API,所以我不打算使用生成的JS代理.

设置信号器集线器连接的JS的相关位是:(记住这是从MVC应用程序提供的,它没有任何信号器支持(当然除了jquery-signalr- {version} .js))

  1. function TestScenarioHandler(signalrHubUrl) {
  2. var self = this;
  3. //Snip irrelevant bits (mostly Knockout initialisation)
  4.  
  5. self.signalrConnectionId = ko.observable();
  6.  
  7. var hubConnection = $.hubConnection(signalrHubUrl,{ useDefaultPath: false });
  8.  
  9. var hubProxy = hubConnection.createHubProxy("testresult");
  10. hubProxy.on("progress",function(value) {
  11. console.log("Hooray! Got a new value from the server: " + value);
  12. });
  13.  
  14. hubConnection.start()
  15. .done(function() {
  16. self.signalrConnectionId(hubConnection.id);
  17. console.log("Connected to signalr hub with connection id " + hubConnection.id);
  18. })
  19. .fail(function() {
  20. console.log("Failed to connect to signalr hub at " + hubConnection.url);
  21. });
  22. }

像这样跨越起源,Firefox网络流量显示(我已经确认Chrome显示同样的事情)GET to

?HTTP://****service.azurewebsites.net/signalr/negotiate clientProtocol = 1.5&安培; connectionData = [{ “名称”: “的TestResult”}]&安培; _ = 1424419288550

请注意,该名称与我的集线器类上的HubName属性的值匹配.

此GET返回HTTP 200,响应为我提供了一个JSON有效负载,其中包含ConnectionId,ConnectionToken和一堆其他字段,表明一切正常. HTTP响应还将Access-Control-Allow-Origin:标头设置为GET源自的域.一切都看起来不错,除了交通停止的地方.

但JS控制台打印“无法连接到信号器集线器http://****service.azurewebsites.net/signalr”

为了验证我没有做任何太愚蠢的事情,我已经为MVC应用程序添加了信号器支持和基本集线器(因此不需要交叉源),并相应地更改了$.hubConnection()和hubConnection.createProxy()调用.当我这样做时,浏览器流量显示相同/信号器/协商?… GET(显然不再交叉原点),但是然后GET到/ signalr / connect?…和/ signalr / start?… .JS控制台还会打印成功消息.

总而言之;

>在服务层启用CORS,信号器/协商GET返回200,看起来是有效的连接ID,以及预期的Access-Control-Allow-Origin:标头.这向我建议服务器端CORS支持正常运行,但信号器连接不成功.
>当我重新配置所以信号器连接不是交叉原点时,一切都按预期工作.

WTF我错过了还是做错了?!也许HttpConfiguration.EnableCors()和IAppBuilder.UseCors(CorsOption)之间存在一些冲突?

解决方法

解决了它.我已经更改了map.UseCors(CorsOptions.AllowAll)来传递CorsPolicy对象,并将SupportsCredentials设置为false,在其他地方读取了Access-Control-Allow-Origin:*与access-control-allow-credentials不兼容:真正.
  1. private static readonly Lazy<CorsOptions> SignalrCorsOptions = new Lazy<CorsOptions>(() =>
  2. {
  3. return new CorsOptions
  4. {
  5. PolicyProvider = new CorsPolicyProvider
  6. {
  7. PolicyResolver = context =>
  8. {
  9. var policy = new CorsPolicy();
  10. policy.AllowAnyOrigin = true;
  11. policy.AllowAnyMethod = true;
  12. policy.AllowAnyHeader = true;
  13. policy.SupportsCredentials = false;
  14. return Task.FromResult(policy);
  15. }
  16. }
  17. };
  18. });
  19.  
  20. public void Configuration(IAppBuilder app)
  21. {
  22. app.Map("/signalr",map =>
  23. {
  24. map.UseCors(SignalrCorsOptions.Value);
  25. map.RunSignalR(new HubConfiguration());
  26. });
  27. //now start the WebAPI app
  28. GlobalConfiguration.Configure(WebApiConfig.Register);
  29. }

将SupportCredentials设置为true会导致在响应中使用实际原点(非*)和access-control-allow-credentials:true重写Access-Control-Allow-Origin标头.

现在它有效.

猜你在找的asp.Net相关文章