1
votes

I have an Azure Cloud Service with a worker role that starts an OWIN web app on startup, which uses SignalR.

Separately, I have a console project that uses the SignalR client library to connect to this worker role and listen for events.

Everything is working when I run the client and the service locally using the Azure emulators.

When I publish the cloud service and point the console application to it and try to connect, I get the following in the SignalR trace logs:

WS Connecting to: ws://myapp.cloudapp.net/signalr/connect?clientProtocol=1.4&transport=webSockets&connectionData=[{"Name":"MessageBusHub"}]&connectionToken=...

OnError(System.Net.WebSockets.WebSocketException (0x80004005): An internal WebSocket error occurred. Please see the innerException, if present, for more details. ---> System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host

It then proceeds to try again using server sent events and long polling with the same error each time.

I'm using the following endpoint in my Cloud service config:

<Endpoints>
  <InputEndpoint name="SignalREndpoint" protocol="http" port="80" localPort="80" />
</Endpoints>

And here is how I create my OWIN web app:

var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["SignalREndpoint"];
string webAppUrl = $"{endpoint.Protocol}://{endpoint.IPEndpoint}";
_webApp = WebApp.Start<Startup>(webAppUrl);

Finally, here's how I configure SignalR:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(CorsOptions.AllowAll);
        app.UseServerAuthentication();
        GlobalHost.DependencyResolver.UseServiceBus(CloudConfigurationManager.GetSetting("ServiceBusConnectionString"), "SignalRMessageBus");
        app.MapSignalR(new HubConfiguration()
        {
            EnableDetailedErrors = true,
        });
    }
}

In the client project I am simply using a HubConnection to connect using the following URL for local testing, http://localhost:80, and the following URL for connecting to the cloud instance, http://myapp.cloudapp.net

I'm not sure what's different between the actual Azure instance and my local emulator that's causing it to not work in the cloud.

Interestingly, if I use the browser to connect to the URL http://myapp.cloudapp.net/signalr/hubs, it works and returns the JS proxy file.

1

1 Answers

0
votes

Have you tried using TCP instead of HTTP as a protocol?

I am not a SignalR expert in any way, but I know about it. When we host our server (XSockets.NET) on Azure worker roles we configure the protocol to be TCP (not HTTP). Have no idea why it would work on localhost though.

Another thing to consider is if the worker role supports websockets? SignalR requires IIS8+ for websocket support and I have no idea if you have access to that in a worker role. There are no options in Azure to turn websockets on/off on a worker role (from what I can see). So my guess is that there is no Microsoft WebSockets in the worker role. By I might be wrong here!

EDIT: Looked at one of my instances and saw that I can change OS and that the default one is 2012 Server. So Microsoft websockets should be available!