1

I have a SignalR server hosted and running in a Owin Web API application running in Azure (Company Service App). From a separate web application, let's say application A (non Azure) I'm connecting to SignalR using the javascript generated proxies:

Where CompanyServiceBaseUrl is set to my site url: (e.g. "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>

Here is my generated folder structure in my client:

enter image description here

When I test locally the SignalR connectivity works fine, but when I test in my environment hosted in Azure connectivity fails.

SignalR negotiate request (between App A and CompanyService):

http://<mysiteurl>/signalr/negotiate (notice that companyservice is missing from URL:

it should be:

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

Here the Reverse proxy rule:

   <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>

Question:

Why is my client connection.Url coming as "/signalr" instead of "/companyservice/signalr" when testing with my Azure site using a reverse proxy?

Finally, looking at this reported SignalR issue, looks like he is experience a very similar thing:

SignalR doesn't work behind a Reverse Proxy

But I'd like to understand what he means by:

"If I use a Reverse-Proxy rule (scan and replace) and set "Url":"/NorthboundWebApiClient/signalr" everything works fine.

I have tried establishing a connection with and without generated proxies specifying my connection url manually var connection = $.hubConnection('/companyservice/signalr', {useDefaultPath: false});, configuring CORS in the client side and no luck.

Here is a related post having problems with cross-domains:

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

Community
  • 1
  • 1
Adolfo Perez
  • 2,834
  • 4
  • 41
  • 61

1 Answers1

2

Four months later a colleague suggested a solution which worked perfectly. His idea was to create a custom custom OwinMiddleware that would add the missing Azure virtual directory to the path in case missing. Something like this:

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);
    }
 }

And then just hook it up in your Owin Configuration method on Startup.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);
        });
     }

The credit goes to my colleague Jake S.

Adolfo Perez
  • 2,834
  • 4
  • 41
  • 61
  • 1
    I just today faced this exact same problem. Your solution worked perfectly. Thank you for sharing this. – tnurmi Oct 20 '21 at 19:11