Я использую .Net 8.0 в Blazor.
У меня есть серверный проект и клиентский проект.
Сервер получает уведомление через метод контроллера, и он должен вызвать метод в концентраторе 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");
}
}
Затем у меня есть контроллер, который будет вызывать метод концентратора:
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 моих клиентов, когда я смотрю на соединение с хабом, я вижу идентификатор соединения.
Если я вызываю свой метод StatusChange в своем контроллере уведомлений, когда я смотрю на идентификатор соединения _notificationHub, он также совпадает с идентификатором моего клиента, поэтому на данный момент все выглядит нормально. Мой код попадает в мой метод в блоке 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;
}
}
}
Таким образом, вы подключаетесь к концентратору в качестве клиента, а затем отправляете сообщение, в то время как предоставленный вами код предназначен только для взаимодействия с концентратором из самого внешнего концентратора, что не рекомендуется по многим причинам.