感觉我在这里失去了理智。
我的服务器的
Program.cs
包含以下行 -
builder.Services.AddSignalR();
app.MapHub<NotificationUserHub>("/NotificationUserHub");
NotificationUserHub
看起来像这样 -
public class NotificationUserHub : Hub<INotificationClient>
{
private readonly IUsersStateContainer _container;
public NotificationUserHub(IUsersStateContainer container) => _container = container;
public async Task AddConnectionToGroup(string groupName)
{
var ctx = Context.ConnectionId;
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
_container.Update(ctx, groupName);
}
public async Task SendNotificationToUser(Notification message)
=> await Clients.Groups(message.To).ReceiveMessage(message);
public override async Task OnDisconnectedAsync(Exception exception)
{
_container.Remove(Context.ConnectionId);
await base.OnDisconnectedAsync(exception);
}
}
我在 Blazor 客户端中的连接代码如下所示 -
var url = $"{WebApiOptions.Value.BaseUrl}NotificationUserHub";
Console.WriteLine($"Hub connection should be {url}");
_hubConnection = new HubConnectionBuilder()
.WithUrl(url)
.WithAutomaticReconnect()
.Build();
_hubConnection.On<Notification>("ReceiveMessage", (message) =>
{
_notificationMessage = message.Type switch
{
Enums.NotificationType.NewMessage => $"New message from {message.From}",
Enums.NotificationType.ConversationClosed => $"Conversation closed by {message.From}",
_ => string.Empty
};
PageInfo.SetUnreadMessageCount(message.UnreadCount);
if (!string.IsNullOrEmpty(_notificationMessage))
{
MessageNotification.Show();
}
});
try
{
await _hubConnection.StartAsync();
await _hubConnection.InvokeAsync("AddConnectionToGroup", PageInfo.CurrentUserEmail);
hubInitialised = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
正如您可能从问题标题中猜到的那样,无论我做什么,我都会在
'InvokeCoreAsync' method cannot be called if the connection is not active
行得到 InvokeAsync
,而我无法终生弄清楚为什么或如何。
Hub 方法
AddConnectionToGroup
永远不会被调用,Hub 状态表示在 InvokeAsync
之前已连接,之后已断开连接。
明显的罪魁祸首是连接 URL,但我已经检查过了,它是正确的。
非常感谢收到的任何建议。
当您调用
Start
方法时,您无法确定连接是否已建立并连接,如文档所述:
Start 是一个承诺,在连接建立后解决 成功建立,或因错误而拒绝。
所以我认为你需要检查连接状态:
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"))
.Build();
hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
var encodedMsg = $"{user}: {message}";
messages.Add(encodedMsg);
StateHasChanged();
});
await hubConnection.StartAsync();
}
private async Task Send()
{
if (hubConnection is not null)
{
await hubConnection.SendAsync("SendMessage", userInput, messageInput);
}
}
// this is the method you need to check the connection state <-------
public bool IsConnected =>
hubConnection?.State == HubConnectionState.Connected;
我从这里得到了这个代码:SignalR with Blazor