如何确定 Signal R 使用的传输方法

cra*_*aus 6 .net c# websocket signalr

我正在编写一个带有信号服务器和 Web 客户端的测试应用程序,我想知道是否有办法确定或让服务器知道客户端正在与服务器建立哪种传输方法。

关于在客户端和服务器之间具有持久双向连接的 websockets 或长轮询,它不断轮询服务器直到服务器响应然后关闭连接,我必须注意传输的任何缺点方法不是持久双向连接之外的网络套接字,特别是如果将有许多长时间运行的请求一个接一个地发出?

我注意到来自客户端的多个请求将由集线器处理并在完成后返回,例如我发送一个请求等待 10 秒然后另一个请求等待 1 秒。集线器将首先响应 1 秒的等待请求,然后是 10 秒的延迟,我很好奇每个请求创建的线程是否通过相同的持久双工连接附加到客户端。

这是我的示例代码。

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);            
    }
}
Run Code Online (Sandbox Code Playgroud)

JQuery 示例。

 $(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());
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

Sta*_*ams 5

对于 ASP.NET Core;

var transportType = Context.Features.Get<IHttpTransportFeature>()?.TransportType;
Run Code Online (Sandbox Code Playgroud)


Lar*_*ner 3

关于运输方式:

您可以检查HubCallerContext.QueryString参数transport

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

关于线程和长时间运行的任务:

每个请求都将在单独的线程上处理,并且当集线器方法完成时,集线器管道将解析客户端承诺。这意味着您可以轻松地阻止您的连接,因为浏览器中的连接限制(通常一次 6 个连接)。

例如:如果您使用长轮询并向服务器发出六个请求,每个请求都触发(或直接执行)一个长时间运行的操作,那么您将有六个待处理的 AJAX 请求,只有在 hub 方法完成后才会得到解决,在此之前您将无法向服务器发出任何进一步的请求。因此,您应该对长时间运行的代码使用单独的任务,并且也不应该等待这些任务,以便集线器调度程序可以毫不延迟地发送其响应。

如果客户端需要知道长时间运行的任务何时完成,那么您应该从服务器发送推送通知,而不是依赖回调.done()