2015-09-25 100 views
1

我有一个SignalR服务器托管并运行在运行在Azure(公司服务应用程序)中的Owin Web API应用程序中。从一个单独的Web应用程序中,我们假设应用程序A(非Azure)使用javascript生成的代理连接到SignalR:反向代理/跨域的SignalR连接问题

其中CompanyServiceBaseUrl设置为我的站点url:(例如“http:// mysite/companyservice” )

<script src="@Url.Content(CompanyServiceBaseUrl + "/Scripts/jquery.signalR-2.2.0.js")"></script> 
    <script src="@Url.Content(CompanyServiceBaseUrl + "/signalr/hubs")" type="text/javascript"></script> 

    <script type="text/javascript"> 
    var hub = $.connection.perform; 

    hub.client.onToast = function() { 
     $("#copyOrganizationSuccessAlert").show(); 
    }; 

    $(document).ready(function() { 
     var event = document.createEvent('Event'); 
     event.initEvent('onOrganizationLock', true, true); 

     onOrganizationLockEvent = function() { 
      document.dispatchEvent(event); 
     }; 

     hub.client.onOrganizationLock = onOrganizationLockEvent; 
    }); 

    $.connection.hub.start().done(function() { 
     hub.server.joinGroup(perform.company.application.clientId); 
    }); 
</script> 

这里是我的客户我生成的文件夹结构:

enter image description here

当我测试本地SignalR连接工作正常,但是当我在我的环境中测试在蓝色海岸举办e连接失败。

SignalR协商要求(附录A和CompanyService之间):

http://<mysiteurl>/signalr/negotiate(注意companyservice从URL中缺少:

它应该是:

http://<mysiteurl>/companyservice/signalr/negotiate 

这里反向代理规则:

<rule name="companyservice" stopProcessing="true"> 
     <match url="^companyservice/(.*)" /> 
     <conditions> 
     <add input="{CACHE_URL}" pattern="^(https?)://" /> 
     </conditions> 
     <action type="Rewrite" url="https://myazuresite.azurewebsites.net/{R:1}" /> 
     <serverVariables> 
     <set name="HTTP_ACCEPT_ENCODING" value="" /> 
     </serverVariables> 
    </rule> 
    </rules> 

问:

为什么使用反向代理与我的Azure的网站进行测试时,我的客户connection.Url来为“/ signalr”,而不是“/ companyservice/signalr”?

最后,看着这个报道SignalR问题,看起来他的经历非常类似的事:

SignalR doesn't work behind a Reverse Proxy

但我想明白他指什么:

如果我使用反向代理规则(扫描和替换)并设置“Url”:“/ NorthboundWebApiClient/signalr”一切正常。

我已经尝试建立一个连接ction with and without generated proxies手动指定我的连接URL var connection = $.hubConnection('/companyservice/signalr', {useDefaultPath: false});,在客户端配置CORS并且没有运气。

这里是具有跨领域问题相关的职位:

How do I get a SignalR hub connection to work cross-domain?

回答

1

四个月后,一个同事建议其工作完全的解决方案。他的想法是创建一个自定义的自定义OwinMiddleware,如果缺失,会将缺失的Azure虚拟目录添加到路径中。类似这样的:

public class SignalRvDirMiddleware : OwinMiddleware 
{ 
    public SignalRvDirMiddleware(OwinMiddleware next) 
    : base(next) 
    { } 

    public override async Task Invoke(IOwinContext context) 
    { 
     var vdir = new PathString("/companyservice"); 
     PathString path = context.Request.PathBase; 
     if (!path.StartsWithSegments(vdir)) 
     { 
      context.Request.PathBase = vdir + path; 
     } 
     await Next.Invoke(context); 
    } 
} 

然后在启动时将它连接到你的Owin配置方法中。CS:

public void Configuration(IAppBuilder appBuilder) 
    { 
     // Branch the pipeline here for requests that start with "/signalr" 
     appBuilder.Map("/signalr", map => 
     { 
      map.Use<SignalRvDirMiddleware>(); 
      map.RunSignalR(hubConfiguration); 
     }); 
    } 

的荣誉属于我的同事杰克S.