我有一个带有 SignalR 端点的 ASP.NET Core 8 Web API:
builder.Services.AddSignalR(hubOptions =>
{
hubOptions.EnableDetailedErrors = true;
}).AddJsonProtocol(jsonOptions => { jsonOptions.PayloadSerializerOptions.PropertyNamingPolicy = null; });
app.MapHub<ChatHub>("/chatHub", options =>
{
});
我里面有一个 Blazor 客户端
OnInitializedAsync
:
HubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("https://localhost:7000/chatHub"), options =>
{
options.Headers.Add("BusinessId", businessId.ToString());
}).AddJsonProtocol(o =>
{
o.PayloadSerializerOptions.PropertyNamingPolicy = null;
}).WithAutomaticReconnect()
.Build();
HubConnection.On<ChatMessageDTO>("ReceiveMessage", async (msg) =>
{
Model?.ChatMessages?.Add(msg);
var messageId = await ChatService.AddNewMessage(msg, Cts.Token);
await InvokeAsync(StateHasChanged);
});
await HubConnection.StartAsync(Cts.Token);
一切正常。我可以从 SignalR 信标向客户端回调发送和接收消息。但是,如果我尝试从中心外部向 Blazor 客户端回调发送组消息,我会得到不一致的结果(如果有)。
这是我的 API 服务:
public class FcmService : IFcmService
{
private readonly IHubContext<ChatHub> _hub { get; }
public FcmService(IHubContext<ChatHub> hub)
{
_hub = hub;
}
public async Task UpdateUi(Message message, CancellationToken token)
{
var group = string.Format("{0}{1}", message.BusinessId, "-Dispatchers");
await _hub.Clients.Group(group).SendAsync("ReceiveMessage", message);
}
}
当我向群组发送消息时,Blazor 客户端回调永远不会被命中。如果我改变这一行:
await _hub.Clients.Group(group).SendAsync("ReceiveMessage", message);
至:
await _hub.Clients.All.SendAsync("ReceiveMessage", message);
每次都有效。
如何从中心外部向群组发送消息?
更新
以下是我添加组的方法:
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
感谢 Brian Parker,我找到了我的问题。如果您使用 WASM 或 InteractiveAuto,请确保将参数作为查询字符串而不是标头传递。我确实喜欢这样:
var url = "";
if (OperatingSystem.IsBrowser())
{
url = string.Format("https://localhost:7000/chatHub?BusinessId={0}", businessId);
}
else
{
url = "https://localhost:7000/chatHub";
}
HubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri(url), options =>
{
options.Headers.Add("BusinessId", businessId.ToString());
}).AddJsonProtocol(o =>
{
o.PayloadSerializerOptions.PropertyNamingPolicy = null;
}).WithAutomaticReconnect()
.Build();