Question

I'm writing a test application with signal r server and a web client and I wanted to know if there is a way to determine or have the server know which transport method the client is establishing with the server.

In regards to websockets which has a persistent two-way connection between the client and server or long polling which keeps polling the server until the server responds and then closes up the connection would there be any downside that I have to be aware of regarding the transport method not being web sockets outside of the persistent two-way connection especially if there are going to be many long running requests being made one after another?

I've noticed that making multiple requests from a client will be handled by the hub and returned when done, example I send a request to wait 10 seconds then a another request to wait 1 second. The Hub will respond to the 1 second wait request first then the 10 second delay, I am curious as to whether there is a thread per request created which is attached to the client via the same persistent duplex connection.

here is my example code.

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(CorsOptions.AllowAll);
        app.MapSignalR();
    }
}
public class RunningHub : Hub
{        
    public void SendLongRunning(string name, string waitFor)
    {
        Clients.All.addMessage(name, "just requested a long running request I'll get back to you when im done");

        LongRunning(waitFor);

        Clients.All.addMessage(name, "I'm done with the long running request. which took " + waitFor + " ms");
    }

    private void LongRunning(string waitFor)
    {
        int waitTime = int.Parse(waitFor);
        Thread.Sleep(waitTime);            
    }
}

JQuery Sample.

 $(function () {
    //Set the hubs URL for the connection
    $.connection.hub.url = "http://localhost:9090/signalr";

    // Declare a proxy to reference the hub.
    var signalHub = $.connection.runningHub;
    $('#url').append('<strong> Working With Port: ' + $.connection.hub.url + '</strong>');

    // Create a function that the hub can call to broadcast messages.
    signalHub.client.addMessage = function (name, message) {
       //handles the response the message here
    };

    // Start the connection.
    $.connection.hub.start().done(function () {
         $('#sendlongrequest').click(function() {
            signalHub.server.sendLongRunning($('#displayname').val(), $('#waitTime').val());
        });
    });
});
Was it helpful?

Solution 2

Regarding the transport method:

You can inspect HubCallerContext.QueryString param transport:

public void SendLongRunning(string name, string waitFor)
{
    var transport = Context.QueryString.First(p => p.Key == "transport").Value;
}

Regarding threading & long-running tasks:

Each request will be handled on a separate thread and the hub pipeline resolves the client-side promise when the hub method completes. This means that you can easily block your connection because of the connection limit in browsers (typically 6 connections at a time).

E.g.: if you use long-polling and you make six requests to the server, each triggering (or directly executing) a long-running operation, then you'll have six pending AJAX requests which only get resolved once the hub method is done, and you won't be able to make any further requests to the server until then. So you should use separate tasks for the long-running code and you should also not await those so the hub dispatcher can send its response without a delay.

If the client needs to know when the long-running task is done, then you should do a push notification from the server instead of relying on the .done() callback.

OTHER TIPS

For ASP.NET Core;

var transportType = Context.Features.Get<IHttpTransportFeature>()?.TransportType;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top