2
votes

I am having some issues with a project that is trying to use SignalR to invoke a datasource read request to all connected clients for a grid data refresh so that users see updates in real time.

This works locally IIS Express while running in Visual Studio using two open chrome windows. SignalR connects in both windows and calls for datasource read execute without error when modifying in either browser window.

When deployed to the server running IIS 10.0.17763.1 the errors appear.

The application is hosted on one server, and if a browser window is open the connection to SignalR works (I receive the console log of connected from the await connection.start call). But when a second browser window is opened or opened on another machine, multiple failures for SingalR begin to appear in the console for each instance of the browser.

The errors are as follows:

Browser Machine 1:

    https://FQDN:2424/trafficWorkflowHub?id=YPCykB9G94tbgzlnZZDi5g 404 (Not Found) 
    Error: Server returned handshake error: An unexpected error occurred during connection handshake. 
    InvalidDataException: Missing required property 'protocol'. Message content: {"arguments": 
   [],"invocationId":"1","target":"UpdateDataSource","type":1} 
    TrafficWorkflow:181 Error: Not Found
        at new HttpError (signalr.js:1487)
        at XMLHttpRequest.xhr.onload (signalr.js:1777)
    TrafficWorkflow:182 connected

Browser Machine 2:

 signalr.js:3927 WebSocket connection to 'wss://FQDN:2424/trafficWorkflowHub?id=2sW4zudCQKoysUQB9mB1vQ' 
failed: Error during WebSocket handshake: Unexpected response code: 404
signalr.js:2684 [2020-09-17T10:57:34.529Z] Information: SSE connected to 
https://FQDN:2424/trafficWorkflowHub?id=E9M_Wkbpt1KBPcHxLHhJXA
signalr.js:1788 POST https://FQDN:2424/trafficWorkflowHub?id=E9M_Wkbpt1KBPcHxLHhJXA 404 (Not Found)
signalr.js:2678 [2020-09-17T10:57:34.060Z] Error: Failed to start the transport 'WebSockets': null

Code example is below.

Client Side Code:

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/trafficWorkflowHub")
    .build();

async function start() {
    try {
        await connection.start().catch(err => console.error(err));
        console.log("connected");
    } catch (err) {
        console.log(err);
        setTimeout(() => start(), 5000);
    }
}

connection.onclose(async () => {
    await start();
});


connection.on("ReceiveUpdates", function () {
    callDataSourceRead();
});

start() is in Document ready section.

invoking the calls to update datasource in the cshtml pages with this call:

 connection.invoke("UpdateDataSource").catch(function (err) {
                    return console.error(err.toString());
                });

Server side code is as follows:

  public class TrafficWorkflowHub : Hub
    {

        public async Task UpdateDataSource()
        {
            await Clients.All.SendAsync("ReceiveUpdates");
        }

    }

In Startup.cs Public void Configure

app.UseSignalR(routes =>
            {
                routes.MapHub<TrafficWorkflowHub>("/trafficWorkflowHub");
           
            });

Public void ConfigureServices

  services.AddSignalR(hubOptions =>
            {
                hubOptions.EnableDetailedErrors = true;
            });
1
Hello. Welcome to stackoverflow. How you configure CORS in your back-end?Kiril1512
in the startup.cs under configure as app.UseCors(builder => { builder.WithOrigins("FQDN:2424/") .AllowAnyHeader() .WithMethods("GET", "POST") .AllowCredentials(); });fishyonionsoup

1 Answers

0
votes

Make sure that you configure CORS like this (order is important):

services.AddCors(options =>
{
    options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("https://yourFrameworkApp.azurewebsites.com")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

And then make sure you have those on the configuration method on startup:

app.UseHttpsRedirection();
app.UseWebSockets();

And don't forget to enable websockets on the server:

enter image description here