我可以使用 IHubContext 接口从服务器代码调用 InvokeAsync,但有时我想强制这些客户端断开连接。
那么,有没有办法将客户端与引用 IHubContext 接口的服务器代码断开连接?
我使用 Microsoft.AspNetCore.SignalR.Client 对在 Windows Server 2016 标准上托管的 SignalR (ASP.NET Core) 应用程序进行负载测试。安装了 Dotnet 核心托管 2.1.1
我无法创建超过 3000 (2950-3050) 个连接。
已经尝试过此处描述的建议:
添加了限制UseKestrel(如果我将值设置为 100 或 1000,这似乎有效):
var host = new WebHostBuilder()
.UseKestrel(options =>
{
options.Limits.MaxConcurrentConnections = 50000;
options.Limits.MaxConcurrentUpgradedConnections = 50000;
})
Run Code Online (Sandbox Code Playgroud)
通过添加以下内容更改了所有 aspnet.config 文件:
<system.web>
<applicationPool maxConcurrentRequestsPerCPU="50000" />
</system.web>
Run Code Online (Sandbox Code Playgroud)
执行了这个命令:
cd %windir%\System32\inetsrv\ appcmd.exe 设置配置 /section:system.webserver/serverRuntime /appConcurrentRequestLimit:50000
添加了Web Service\Current Connections - Maximum Connections的性能计数器。并且最大连接数增加到 3300 并停止。
服务器日志没有异常。但我感觉系统有一些限制。
服务器 IIS 日志仅包含以下内容:
获取 …
从这里开始,它指出
所有客户端都将使用相同的 URL 与您的服务建立 SignalR 连接(“/signalr”或您的自定义 URL,如果您指定了一个),并且该连接用于服务定义的所有集线器。
与在单个类中定义所有集线器功能相比,多个集线器没有性能差异。
我想这样做的原因只是因为我唯一的集线器正在成为神级,但是,我找不到在 .NET Core 中做多个集线器的方法(同时共享一个连接)。我希望我能这样做,然后我就可以像在 Web API 中那样管理我的代码。
一种可能的解决方案可能会创建多个连接,但我必须在我的客户端管理不同的连接,只是为了防止服务器代码上的上帝类。
从这里开始,有人指出将方法映射到外部类是一种解决方法。这是唯一的解决方法吗?
我正在学习 SignalR 但遇到了障碍。
我有一个 Azure 函数,已成功发布到 Azure SignalR 托管服务(在无服务器模式下配置)
我一直在关注这个快速入门:
快速入门:使用 C# 通过 Azure Functions 和 SignalR 服务创建聊天室
我想要实现的基本上是将来自服务器的消息接收到我的客户端应用程序中。为了原型化,我创建了一个控制台应用程序。
我添加了以下 Nuget 包
Microsoft.AspNetCore.SignalR.Client -版本 1.1.0 Microsoft.Azure.WebJobs.Extensions.SignalRService
所有基础设施似乎都工作正常 - 我的假设是我可以在以下地址运行演示网站,将其指向我的本地实例(或托管在 Azure 中的实例) https://azure- samples.github.io/signalr-service-quickstart-serverless-chat/demo/chat-v2/
我的 AzureFunction 发布的消息直接发布到聊天窗口中。
如何将这些消息打印到控制台?
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using System;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.ReadKey();
var connection = new HubConnectionBuilder().WithUrl("http://localhost:7071/api").Build();
connection.On<SignalRMessage>("newMessage", (message) =>
{
Console.WriteLine(message.Arguments);
});
connection.On("newMessage", (string server, string message) =>
{
Console.WriteLine($"Message from …Run Code Online (Sandbox Code Playgroud) SignalR 客户端有两个 nuget 包:
Microsoft.AspNetCore.SignalR.Client和Microsoft.AspNetCore.SignalR.Client.Core。
两者都是 ASP.NET Core,但我找不到任何信息,为什么它们都存在。
可能 Client.Core 的功能有限,但这只是我的猜测。
在Web API中,所有异常都可以通过中间件来处理。在 Asp.Net Core 5.0 中,集线器过滤器将完成这项工作。
但是如何在 SignalR 集线器中处理 Asp.Net Core 3.1 中的异常呢?有没有唯一的方法可以在每个方法中编写 try/catch ,如下所示?
[Authorize]
public class OrdersHub : BaseHub
{
public async Task GetOrder(Guid requestId, int orderId)
{
try
{
var data = await ordersService.GetOrderAsync(orderId);
await Clients.Caller.SendAsync("GetOrderResult", requestId, result);
}
catch (Exception ex)
{
await Clients.Caller.Reject(requestId, ex);
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 SignalR 和 .Net 5.0,并利用集线器过滤器对 SignalR Hub 的传入调用执行代码。
我正在寻找一种方法来对从集线器到客户端的传出消息执行相同的操作,但似乎没有其他选择。或者,我希望在发送内置Ping 消息时专门挂接并执行代码。
看起来旧版本的 HubPipeLineModule 中曾经可以实现类似的功能,但我无法找到任何方法在当前的 SignalR 中实现此目的。这可能吗?
我正在尝试实现 SignalR 以便使用来自角度前端应用程序的数据。
我已经检查了谷歌上能找到的所有结果,但仍然无法解决我的问题。
我收到的错误是:
无法访问已释放的上下文实例。导致此错误的一个常见原因是处置从依赖项注入解析的上下文实例,然后尝试在应用程序的其他位置使用相同的上下文实例。如果您在上下文实例上调用“Dispose”或将其包装在 using 语句中,则可能会发生这种情况。如果您使用依赖项注入,则应该让依赖项注入容器负责处理上下文实例。对象名称:“AdminContext”
控制器
[Route("api/[controller]")]
[ApiController]
public class ChartController : ControllerBase
{
private IHubContext<ChartHub> _hub;
private readonly ILiveMonitoringService _service;
public ChartController(IHubContext<ChartHub> hub, ILiveMonitoringService service)
{
_hub = hub;
_service = service;
}
public IActionResult Get()
{
var timerManager = new TimerManager(async () => await _hub.Clients.All.SendAsync("transferchartdata", await _service.GetAllAsync()));
return Ok(new { Message = "Request Completed" });
}
}
Run Code Online (Sandbox Code Playgroud)
服务
public Task<List<LiveMonitoring>> GetAllAsync()
{
return _repository.GetAll().Take(100).ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
存储库
public IQueryable<TEntity> GetAll()
{
try
{
return _adminContext.Set<TEntity>();
} …Run Code Online (Sandbox Code Playgroud) signalr entity-framework-core asp.net-core asp.net-core-signalr
我们已在 Azure Web 应用程序(Windows 应用服务计划)上运行的 ASP.NET Core 5.0 Web 项目上启用了 SignalR。我们的 SignalR 客户端是使用 NPM 包(版本 5.0.11)的 Angular 客户端@microsoft/signalr。
我们的枢纽位于/api/hub/notification。
对于大多数客户端来说,一切都按预期进行,Web 套接字连接已建立,我们可以从客户端调用到服务器的方法,反之亦然。
对于我们的一些客户,我们看到在短时间内收到大量请求(每个客户端每分钟多个请求)POST /api/hub/notification/negotiate。POST /api/hub/notification自从我们看到请求以来,这些客户端似乎切换到长轮询而不是使用 Web 套接字POST /api/hub/notification。
我们怀疑受影响的客户端可能位于代理或防火墙后面,这些代理或防火墙禁止 Web 套接字,因此连接首先切换为长轮询。
以下屏幕截图显示了单个用户在短时间内向集线器端点发出的请求。该列表很长,因为只要用户打开我们的网站,这种模式就会重复。我们看到两个奇怪的事情:
/negotiate每 15 秒重复调用两次。POST /notification?id=<connectionId>恰好需要 15 秒,并且具有相同连接 ID 的后续调用将返回 404 响应。然后该模式重复并/negotiate再次被调用。出于测试目的,我们仅在客户端中启用长轮询。这也符合我们的预期。不幸的是,我们目前无法访问发生此行为的用户的浏览器或网络,因此我们很难重现该问题。
更多注意事项:
我们使用 AWS kubernetes 集群 (EKS) 以及 ALB/Ingress 和 redis 缓存来进行信号器连接。如果我们的副本集为 3,连接到服务会随机抛出 404 错误。设置选项时:
SkipNegotiation = true
Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets
Run Code Online (Sandbox Code Playgroud)
一切似乎都有效。我找不到设置SkipNegotation为 true 的任何缺点。false但找不到这是否有任何副作用(默认设置一定有原因)。
设置会SkipNegotation导致true任何进一步的问题吗?
正在运行的示例代码:
Console.WriteLine("Start");
HubConnection connection = new HubConnectionBuilder()
.WithUrl("https://<url>/api/v1/taskboard", o =>
{
o.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
o.SkipNegotiation = true;
})
.WithAutomaticReconnect()
.Build();
await connection.StartAsync();
connection.On<string>("ReceiveMessage", message =>
{
Console.WriteLine(message);
});
for (int i = 0; i < 20; i++)
{
await connection.InvokeAsync("SendMessage", $"Hello {i}");
await Task.Delay(55);
}
await connection.StopAsync();
await connection.DisposeAsync(); …Run Code Online (Sandbox Code Playgroud) c# websocket signalr kubernetes-ingress asp.net-core-signalr
asp.net-core ×4
c# ×4
signalr ×4
azure ×2
signalr-hub ×2
.net-5 ×1
asp.net ×1
exception ×1
long-polling ×1
websocket ×1