我在 Blazor 中使用 .Net 8.0。
我有一个服务器项目和一个客户端项目。
服务器通过控制器方法接收通知,这应该调用 signalR 集线器上的方法将通知“推送”给所有客户端。问题是 Hub 方法永远不会被调用。
在服务器上我有以下代码:
在program.cs文件中:
builder.Services.AddSignalR();
.....
app.MapHub<NotificationHub>("/notificationhub");
我已经创建了我的中心:
public class NotificationHub : Hub
{
[HubMethodName("SendBookingStatusUpdate")]
public async Task SendBookingStatusUpdate()
{
await Clients.All.SendAsync("ReceiveBookingStatusUpdate");
}
}
然后我有一个将调用 hub 方法的控制器:
public class NotificationController : ControllerBase
{
private readonly IHubContext<NotificationHub> _notificationHub;
public NotificationController(IHubContext<NotificationHub> notificationHub)
{
_notificationHub = notificationHub;
}
[HttpPost("statuschange")]
public async Task StatusChange()
{
try
{
await _notificationHub.Clients.All.SendAsync("SendBookingStatusUpdate");
}
catch (Exception ex)
{
throw;
}
}
}
在我的客户端的一个代码隐藏页面上,我有:
private HubConnection? hubConnection;
protected override async Task OnInitializedAsync()
{
await ScreenTasks();
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/notificationhub"))
.WithAutomaticReconnect()
.Build();
hubConnection.Closed += async (err) => { await Task.Delay(4000); await hubConnection.StartAsync(); };
hubConnection.On("ReceiveBookingStatusUpdate", async () =>
{
await ScreenTasks();
StateHasChanged();
});
await hubConnection.StartAsync();
}
public async ValueTask DisposeAsync()
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}
}
当我单步执行代码时,在客户端 onInitializedAsync 方法末尾,当我查看 hubconnection 时,我可以看到连接 id。
如果我在通知控制器中调用 StatusChange 方法,当我查看 _notificationHub 连接 ID 时,这也与我的客户端的 Id 相同,因此此时一切似乎都正常。我的代码在我的 try 块中命中了我的方法,然后就通过了。它不会进入 notificationHub SendBookingStatusUpdate 方法,并且代码不会命中我的 catch 块。我需要做什么才能确保我的集线器方法被调用。
从 Nuget 安装此软件包:Microsoft.AspNetCore.SignalR.Client
然后按如下方式修改您的控制器:
public class NotificationController : ControllerBase
{
[HttpPost("statuschange")]
public async Task StatusChange()
{
try
{
//Replace with your application url that hosts the hub
var connection = new HubConnectionBuilder().WithUrl("https://localhost:7234/notificationhub").Build();
//Connect to SignalR hub as client
await connection.StartAsync();
//Check if connection established
if (connection.State == HubConnectionState.Connected)
{
//Invoke SignalR method
await connection.InvokeAsync("SendBookingStatusUpdate");
}
}
catch (Exception ex)
{
throw;
}
}
}
通过这种方式,您可以作为客户端连接到集线器,然后发送消息,而您提供的代码只是从集线器外部与集线器交互,出于多种原因,不建议这样做