'错误:服务器超时已过,没有收到来自服务器的消息.'.
我正在尝试调试一些服务器端代码,而当我这样做时,客户端会在不到一分钟的时间内断开连接.
我只使用SignalR与客户端通信,而没有控制器.
是否有任何设置可以禁用超时或至少使它比现在更长?
我的launchSettings.json:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:26793",
"sslPort": 44386
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_HTTPS_PORT": "44386"
}
},
"Api": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "https://localhost:5001;http://localhost:5000"
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 使用.net 4.7中的signalR,我们能够将两个变量从客户端应用程序传递到signalR服务器.这是代码片段:
public class MyHub : Hub
{
protected (string myVar1, string myVar2) GetValues() =>
(
Context.QueryString["MyVariable1"] ?? string.Empty,
Context.QueryString["MyVariable2"] ?? string.Empty,
);
}
Run Code Online (Sandbox Code Playgroud)
javascript客户端会将这些变量设置如下:
$.connection.hub.qs = {'MyVariable1' : 'val1', 'MyVariable2' : 'val2'};
Run Code Online (Sandbox Code Playgroud)
现在,我们正在尝试迁移到.net核心2.0应用程序的signalR的alpha版本.阻止程序是我们不能再使用此方法来获取myVar1和myVar2值.不仅QueryString不可用,还有标题.为了能够将变量从客户端应用程序(Typescript)甚至.net核心应用程序传递到signalR服务器端,最好的方法是什么?另外 - 如何在客户端设置变量?
我将 SignalR 与 ASP.NET Core 2.0 结合使用,并尝试向特定用户发送通知,如下所示:
_notification.Clients.User(id).InvokeAsync("SendMes");
Run Code Online (Sandbox Code Playgroud)
其中 _notification 是 IHubContext。但这不起作用。当我向所有用户发送通知时,一切都很好,所有用户都会收到通知。但是当我将其发送给特定用户时,什么也没有发生。在连接中我需要用户,但似乎他没有用户ID。那么我该怎么做呢?通过访问身份和声明?如果是这样,该怎么做?
我是一名新用户,正在努力从 ASP.NET Core Blazor 服务器页面正常关闭辅助 signalR 客户端。
我正在 Blazor 服务器页面的首次渲染上设置辅助 signalR 客户端连接。当通过浏览器选项卡关闭页面时,我试图关闭此辅助 signalR 客户端连接。
在撰写本文时,DisposeAsync通过浏览器选项卡关闭页面时似乎不会触发。然而,该Dispose方法被触发。此外,在 Safari 13.0.5 中,Dispose关闭浏览器选项卡时不会触发该方法?Opera、Firefox 和 Chrome 都Dispose在关闭浏览器选项卡时触发。通过 macOS Catalina v10.15.7 将 Safari 更新至 v14.0(15610.1.28.9、15610)修复了此问题。
目前,我正在调用DisposeAsyncfromDispose以关闭 signalR 连接。我使用以下代码关闭客户端连接:
...
Logger.LogInformation("Closing secondary signalR connection...");
await hubConnection.StopAsync();
Logger.LogInformation("Closed secondary signalR connection");
...
Run Code Online (Sandbox Code Playgroud)
该StopAsync方法似乎被阻止,即没有输出“关闭辅助信号R连接”的消息。尽管如此,OnDisconnectedAsync我的服务器集线器的处理程序显示连接已断开。这与本期中描述的行为类似。
如何在ASP.NET Core 3.1中正确处理 signalR 连接?
完整的代码清单如下所示:
处理 signalR 连接
#region …Run Code Online (Sandbox Code Playgroud) signalr signalr.client asp.net-core asp.net-core-signalr blazor-server-side
只是要事先弄清楚,这个问题是关于.Net Core SignalR的,而不是以前的版本。
新的SignalR在IIS后面的WebSockets出现问题(我无法让它们在Chrome / Win7 / IIS Express上运行)。因此,我使用服务器发送事件(SSE)。但是,问题在于大约2分钟后那些超时,连接状态从2变为3。自动重新连接已被删除(显然,在以前的版本中,它的运行情况并不理想)。
我现在想实现一个心跳计时器,以阻止客户端超时,每30秒滴答一滴就可以很好地完成工作。
11月10日更新
我现在设法实现了服务器端心跳信号,该信号基本上取自Ricardo Peres的https://weblogs.asp.net/ricardoperes/signalr-in-asp-net-core
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider) app.UseSignalR(routes =>
{
routes.MapHub<TheHubClass>("signalr");
});
TimerCallback SignalRHeartBeat = async (x) => {
await serviceProvider.GetService<IHubContext<TheHubClass>>().Clients.All.InvokeAsync("Heartbeat", DateTime.Now); };
var timer = new Timer(SignalRHeartBeat).Change(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(30));
Run Code Online (Sandbox Code Playgroud)
对于HubClass,我添加了 public async Task HeartBeat(DateTime now) => await Clients.All.InvokeAsync("Heartbeat", now);
显然,计时器,正在发送的数据(我只是在发送DateTime)和客户端方法名称都可以不同。
见下面的评论;计时器回调不应再使用。现在,我实现了一个IHostedService(或更确切地说是抽象BackgroundService)来做到这一点:
public class HeartBeat : BackgroundService
{
private readonly IHubContext<SignalRHub> _hubContext;
public HeartBeat(IHubContext<SignalRHub> hubContext)
{
_hubContext = hubContext;
}
protected …Run Code Online (Sandbox Code Playgroud) asp.net-core-mvc asp.net-core-2.0 asp.net-core-2.1 asp.net-core-signalr
我正在使用Microsoft.AspNetCore.SignalR(最新版本),并希望从另一个不是的对象中获取集线器上下文Controller.在"完整"SignalR中,我可以使用GlobalHost.ConnectionManager.GetHubContext<MyCoolHub>();
我已经看到很多例子只是Microsoft.AspNetCore.SignalR.IHubContext<MyCoolHub>作为一个参数添加到一个Ctor Controller,但没有例子(那是有效的).
ETA:
所以,这就是我的工作.这个hacky?
public class MyHub : Hub
public static IHubContext<MyHub> GlobalContext { get; private set; }
public MyHub(IHubContext<MyHub> ctx){
GlobalContext = ctx;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以这样称呼它:
await MyHub.GlobalContext.Clients.All.InvokeAsync(...)
Run Code Online (Sandbox Code Playgroud) 如何将 SignalR 集线器上下文传递给 ASP .NET Core 2.1 上的 Hangfire 作业?
似乎由于将参数传递给 Hangfire 是通过序列化/反序列化完成的,因此 Hangfire 似乎很难重建 SignalR 集线器上下文。
我使用以下方法安排工作(在我的控制器中):
BackgroundJob.Schedule(() => _hubContext.Clients.All.SendAsync(
"MyMessage",
"MyMessageContent",
System.Threading.CancellationToken.None),
TimeSpan.FromMinutes(2));
Run Code Online (Sandbox Code Playgroud)
然后 2 分钟后,当作业尝试执行时,出现错误:
Newtonsoft.Json.JsonSerializationException:无法创建 Microsoft.AspNetCore.SignalR.IClientProxy 类型的实例。类型是接口或抽象类,不能被实例化。
任何的想法?
更新 1
我最终使用了 Startup.cs 中定义的静态上下文,并从 Configure() 分配
hbctx = app.ApplicationServices.GetRequiredService<IHubContext<MySignalRHub>>();
Run Code Online (Sandbox Code Playgroud)
所以现在 Hangfire 安排了一个使用静态上下文的集线器助手:
BackgroundJob.Schedule(() => new MyHubHelper().Send(), TimeSpan.FromMinutes(2));
Run Code Online (Sandbox Code Playgroud)
并且集线器助手获取上下文 Startup.hbctx
即使这有效,它也有点臭
更新 2
我也尝试在没有构造函数注入的情况下使用Access SignalR Hub 中的方法:
我的后台作业调度变成了:
BackgroundJob.Schedule(() => Startup.GetService().SendOutAlert(2), TimeSpan.FromMinutes(2));
但是这一次,当我到达上述行时,我有一个例外:
执行请求 System.ObjectDisposedException 时发生未处理的异常:无法访问已处理的对象。对象名称:'IServiceProvider'。
更新 3
谢谢大家。解决方案是创建一个助手,通过其构造函数通过 DI 获取集线器上下文,然后使用 hangfire 将助手方法 Send …
我需要向特定用户发送通知。我正在使用 dotnet core 3.1。用于通知的 ASPNETCORE signalR。我可以将消息发送给所有客户端,但无法为特定用户发送消息。
编辑1
我的中心看起来像:
public class NotificationHub : Hub
{
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception ex)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, Context.User.Identity.Name);
await base.OnDisconnectedAsync(ex);
}
}
Run Code Online (Sandbox Code Playgroud)
我从控制器调用 SendAsync 方法如下:
private IHubContext<NotificationHub> _hub;
public NotificationController(IHubContext<NotificationHub> hub)
{
_hub = hub;
}
[HttpGet]
public IActionResult Get()
{
//_hub.Clients.All.SendAsync("SendMessage",
_hub.Clients.All.SendAsync("SendMessage",
new
{
val1 = getRandomString(),
val2 = getRandomString(),
val3 = getRandomString(),
val4 = getRandomString()
});
return Ok(new { Message …Run Code Online (Sandbox Code Playgroud) 目前,我们使用 SignalR 在 UI 客户端上从后端接收实时消息。UI 客户端在在线并连接到 SignalR 时接收消息,并在断开连接时错过消息(例如:用户关闭页面并且 SignalR 断开客户端连接)。但是,现在我们需要向用户显示所有消息,包括 UI 客户端离线时 SignalR 发送的消息。SignalR 可以支持这种场景吗?该要求类似于 UI 客户端消息的持久队列,但我们使用 SignalR 向所有客户端广播消息。
signalr signalr-hub signalr.client signalr-backplane asp.net-core-signalr