3
votes

I'm moving an ASP.NET Core app from Windows Server to Ubuntu with Nginx v1.15.5, and I've been struggling to get SignalR to work. The websocket connection keeps getting a 200 return code instead of being upgraded. All other aspects of the app works.

Everything works fine on Windows with IIS, IIS Express, and local Kestrel dev server, so I'm guessing I'm missing something with the Nginx proxy config.

I've tried everything listed in the below References section. Below is the current state of things (Startup and my site's Nginx config). The logs all look like the ones listed below.

The site is public, so you can test it with dev tools to take a look at the requests/responses.

Site: https://my.doxm.app/
Login ID: [email protected]
Password: P@ssword1

The SignalR connection starts right after logging in.

Any help would be appreciated.

In Startup.cs

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, DataService dataService)
    {
        DataService = dataService;
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
            //app.UseHttpsRedirection();
        }

        ConfigureStaticFiles(app);

        app.UseCookiePolicy();

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.UseAuthentication();

        app.UseSignalR(routes =>
        {
            routes.MapHub<BrowserSocketHub>("/BrowserHub", options => 
            {
                options.ApplicationMaxBufferSize = 500000;
                options.TransportMaxBufferSize = 500000;
            });
            routes.MapHub<DeviceSocketHub>("/DeviceHub", options =>
            {
                options.ApplicationMaxBufferSize = 500000;
                options.TransportMaxBufferSize = 500000;
            });
            routes.MapHub<RCDeviceSocketHub>("/RCDeviceHub");
            routes.MapHub<RCBrowserSocketHub>("/RCBrowserHub");
        });
        app.UseMvcWithDefaultRoute();
        dataService.SetAllMachinesNotOnline();
        dataService.CleanupEmptyOrganizations();
        dataService.CleanupOldRecords();
    }

Nginx site config

server {
    listen        80;
    server_name   my.doxm.app *.my.doxm.app;
    location / {
            proxy_pass          http://localhost:5000;
            include             /etc/nginx/proxy_params;
            proxy_http_version  1.1;
            proxy_set_header    Upgrade $http_upgrade;
            proxy_set_header    Connection keep-alive;
            proxy_cache_bypass  $http_upgrade;
        }

    location /BrowserHub {
            proxy_pass          http://localhost:5000;
            include             /etc/nginx/proxy_params;
            proxy_http_version  1.1;
            proxy_set_header    Upgrade $http_upgrade;
            proxy_set_header    Connection "upgrade";
            proxy_cache_bypass  $http_upgrade;
        }


        # Other locations will go here once I get the above one working.

        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/my.doxm.app/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/my.doxm.app/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Contents of /etc/nginx/proxy_params

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

References:

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2

SignalR in ASP.NET Core behind Nginx

https://kimsereyblog.blogspot.com/2018/07/signalr-with-asp-net-core.html

Asp.Net Core 2 SignalR Ubuntu Xamarin Android

https://www.nginx.com/blog/websocket-nginx/

http://nginx.org/en/docs/http/websocket.html

Logs

2019/01/09 14:05:24 [alert] 24344#24344: *74 open socket #3 left in connection 5
2019/01/09 14:05:24 [alert] 24344#24344: *79 open socket #13 left in connection 8
2019/01/09 14:05:24 [alert] 24344#24344: aborting
2019/01/09 14:11:20 [alert] 24395#24395: *200 open socket #13 left in connection 4
2019/01/09 14:11:20 [alert] 24395#24395: *195 open socket #3 left in connection 15
2019/01/09 14:11:20 [alert] 24395#24395: aborting
2019/01/09 14:26:12 [alert] 24845#24845: *1 open socket #3 left in connection 3
2019/01/09 14:26:12 [alert] 24845#24845: *6 open socket #13 left in connection 4
2019/01/09 14:26:12 [alert] 24845#24845: aborting
2019/01/09 14:36:49 [alert] 25082#25082: *19 open socket #3 left in connection 3
2019/01/09 14:36:49 [alert] 25082#25082: *24 open socket #13 left in connection 4
2019/01/09 14:36:49 [alert] 25082#25082: aborting
2019/01/09 14:48:06 [alert] 26806#26806: *62 open socket #13 left in connection 3
2019/01/09 14:48:06 [alert] 26806#26806: *57 open socket #3 left in connection 4
2019/01/09 14:48:06 [alert] 26806#26806: aborting
2019/01/09 14:49:12 [alert] 26933#26933: *1 open socket #3 left in connection 3
2019/01/09 14:49:12 [alert] 26933#26933: *5 open socket #14 left in connection 5
2019/01/09 14:49:12 [alert] 26933#26933: aborting
1

1 Answers

1
votes

The issue ended up being unrelated to Nginx. There was a DLL version mismatch for System.Net.WebSockets.WebSocketProtocol.dll. WinSCP was apparently not overwriting it on deploy. I would have expected an error response from this, but it was still sending back 200 after the exception.