SignalR Core,连接客户端时未从服务器获得响应
SignalR Core, not getting response from server when client is connected
我正在处理 SignalR Clinet-Server 连接。我的服务器是 WebApi Core 2.1
,我的客户端是 WPF .NET Framework 4.7.2
。
在客户端,我有一个 singleton
集线器服务,其中一个实例用于接收来自服务器的消息:
using System.Collections.ObjectModel;
using Microsoft.AspNetCore.SignalR.Client;
public class HubService
{
//singleton
public static HubService Instance { get; } = new HubService();
public ObservableCollection<string> Notifications { get; set; }
public async void Initialize()
{
this.Notifications = new ObservableCollection<string>();
var hubConnection = new HubConnectionBuilder()
.WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
.Build();
hubConnection.On<string>("ReciveServerUpdate", update =>
{
//todo
});
await hubConnection.StartAsync();
}
}
我将其初始化为单例:
public MainWindowViewModel()
{
HubService.Instance.Initialize();
}
我在调试时,在 MainWindowViewModel
上我点击了那个 HubService
。
Server
一侧看起来像这样。
Hub
:
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
public class NotificationsHub : Hub
{
public async Task GetUpdateForServer(string call)
{
await this.Clients.Caller.SendAsync("ReciveServerUpdate", call);
}
}
我正在控制器的方法中以这种方式触发发送消息:
[HttpPost]
public async Task<IActionResult> PostTask([FromBody] Task task)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
this.taskService.Add(task);
//here im calling sending message. When im debugging
//i see one connection from my WPF with unique ConnectionId
await this.notificationsHub.Clients.All.SendAsync("ReciveServerUpdate", "New Task in database!");
return this.Ok(task);
}
正如我之前所写,当我调试我的 WebApi
时,在 Clients
中我只有一个连接来自我的 WPF
。当我关闭 WPF
、connection count = 0
时,连接工作正常。
但是当我调用 SendAsync()
时,我没有在 hubConnection.On
中收到 WPF
中的任何信息。有趣的是,昨天它完美运行。
那么,我关于将 HubService
设为静态 singleton
的想法是否正确?如果是,为什么当我的 WPF
连接到它时,我无法通过 SignalR
接收来自 WebApi
的消息?
我昨天问了一些类似的问题,但我找到了解决方案。昨天,我的方法奏效了,当我收到来自 WebApi
的任何消息时,我可以点击 hubConnection.On
。 。
编辑
向控制器注入HUb
:
private readonly ITaskService taskService;
private readonly IHubContext<NotificationsHub> notificationsHub;
public TaskController(ITaskService taskService, IHubContext<NotificationsHub> notificationsHub)
{
this.taskService = taskService;
this.notificationsHub = notificationsHub;
}
和Startup.cs
只有SignalR
的东西(我删除了其他与信号无关的东西):
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSignalR(routes => routes.MapHub<NotificationsHub>("/Notifications"));
}
EDIT2
这是我可以获得的连接,当我的客户 WPF
将注册他的连接时:
我用各种客户端(wpf/console/even 用浏览器)试过你的代码,它对我来说总是很好用。当我向 PostTask
.
发送请求时,总是会调用 hubConnection.On<string>("ReciveServerUpdate", update => {//todo});
我不确定为什么(有时)它对您不起作用。但是,当 SignalR 客户端连接到服务器但没有收到来自服务器的消息时,可能有两个原因:
- 您的
PostTask([FromBody] Task task)
操作方法未执行。假设这是一个 ApiController
方法,如果浏览器不小心发出一个带有 application/www-x-form-urlencoded
的 Content-Type
的请求,则根本不会执行 Clients.All.SendAsync(..., ...);
的调用。
SigalR 客户端 (hubConnection.On<>(method,handler)
) 的处理程序必须具有与调用完全相同的参数列表才能接收消息。我们在处理这个问题的时候一定要非常小心。
最后最好加个参考Microsoft.Extensions.Logging.Console
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.*" />
这样我们就可以启用日志记录来进行故障排除:
var hubConnection = new HubConnectionBuilder()
.WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
.ConfigureLogging(logging =>{
logging.AddConsole(); // enable logging
})
.Build();
我正在处理 SignalR Clinet-Server 连接。我的服务器是 WebApi Core 2.1
,我的客户端是 WPF .NET Framework 4.7.2
。
在客户端,我有一个 singleton
集线器服务,其中一个实例用于接收来自服务器的消息:
using System.Collections.ObjectModel;
using Microsoft.AspNetCore.SignalR.Client;
public class HubService
{
//singleton
public static HubService Instance { get; } = new HubService();
public ObservableCollection<string> Notifications { get; set; }
public async void Initialize()
{
this.Notifications = new ObservableCollection<string>();
var hubConnection = new HubConnectionBuilder()
.WithUrl(UrlBuilder.BuildEndpoint("Notifications"))
.Build();
hubConnection.On<string>("ReciveServerUpdate", update =>
{
//todo
});
await hubConnection.StartAsync();
}
}
我将其初始化为单例:
public MainWindowViewModel()
{
HubService.Instance.Initialize();
}
我在调试时,在 MainWindowViewModel
上我点击了那个 HubService
。
Server
一侧看起来像这样。
Hub
:
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
public class NotificationsHub : Hub
{
public async Task GetUpdateForServer(string call)
{
await this.Clients.Caller.SendAsync("ReciveServerUpdate", call);
}
}
我正在控制器的方法中以这种方式触发发送消息:
[HttpPost]
public async Task<IActionResult> PostTask([FromBody] Task task)
{
if (!this.ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
this.taskService.Add(task);
//here im calling sending message. When im debugging
//i see one connection from my WPF with unique ConnectionId
await this.notificationsHub.Clients.All.SendAsync("ReciveServerUpdate", "New Task in database!");
return this.Ok(task);
}
正如我之前所写,当我调试我的 WebApi
时,在 Clients
中我只有一个连接来自我的 WPF
。当我关闭 WPF
、connection count = 0
时,连接工作正常。
但是当我调用 SendAsync()
时,我没有在 hubConnection.On
中收到 WPF
中的任何信息。有趣的是,昨天它完美运行。
那么,我关于将 HubService
设为静态 singleton
的想法是否正确?如果是,为什么当我的 WPF
连接到它时,我无法通过 SignalR
接收来自 WebApi
的消息?
我昨天问了一些类似的问题,但我找到了解决方案。昨天,我的方法奏效了,当我收到来自 WebApi
的任何消息时,我可以点击 hubConnection.On
。
编辑
向控制器注入HUb
:
private readonly ITaskService taskService;
private readonly IHubContext<NotificationsHub> notificationsHub;
public TaskController(ITaskService taskService, IHubContext<NotificationsHub> notificationsHub)
{
this.taskService = taskService;
this.notificationsHub = notificationsHub;
}
和Startup.cs
只有SignalR
的东西(我删除了其他与信号无关的东西):
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSignalR(routes => routes.MapHub<NotificationsHub>("/Notifications"));
}
EDIT2
这是我可以获得的连接,当我的客户 WPF
将注册他的连接时:
我用各种客户端(wpf/console/even 用浏览器)试过你的代码,它对我来说总是很好用。当我向 PostTask
.
hubConnection.On<string>("ReciveServerUpdate", update => {//todo});
我不确定为什么(有时)它对您不起作用。但是,当 SignalR 客户端连接到服务器但没有收到来自服务器的消息时,可能有两个原因:
- 您的
PostTask([FromBody] Task task)
操作方法未执行。假设这是一个ApiController
方法,如果浏览器不小心发出一个带有application/www-x-form-urlencoded
的Content-Type
的请求,则根本不会执行Clients.All.SendAsync(..., ...);
的调用。 SigalR 客户端 (
hubConnection.On<>(method,handler)
) 的处理程序必须具有与调用完全相同的参数列表才能接收消息。我们在处理这个问题的时候一定要非常小心。最后最好加个参考
Microsoft.Extensions.Logging.Console
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.*" />
这样我们就可以启用日志记录来进行故障排除:
var hubConnection = new HubConnectionBuilder() .WithUrl(UrlBuilder.BuildEndpoint("Notifications")) .ConfigureLogging(logging =>{ logging.AddConsole(); // enable logging }) .Build();