我有一个 ASP.NET Core Web 服务和一个 Blazor 客户端。当我的方法在 Web 服务中的类(而不是控制器)中触发时,我想将数据发送给我的客户端。
当我使用控制器时,它可以工作,但在常规课程中,我看到
clients.All
是空的,即使 OnConnectedAsync
被触发(表示已连接)
据我了解,
HubContext
不是单例而是瞬态的。我尝试了很多方法,但连接的客户端列表是空的。
在我的
Startup
:
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.InstallServicesInAssembly(Configuration);
services.AddTransient<IGeneralStockMarketHandler, GeneralStockMarketHandler>();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", policy =>
{
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<NotificationHub>("/notificationhub");
endpoints.MapControllers();
});
}
我的中心:
public class NotificationHub : Hub
{
public override Task OnConnectedAsync()
{
Console.WriteLine("Client has connected");
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
Console.WriteLine("Client has disconnected");
return base.OnDisconnectedAsync(exception);
}
}
我注入的
GeneralStockMarketHandler
类IHubContext
:
public GeneralStockMarketHandler(IHubContext<NotificationHub> hubContext)
{
_hubContext = hubContext;
}
private async void MyStockMarketHandler_OnDataReceived(StreamSnapshotResponseModel response)
{
await HandleStreamSnapshotResponse(response);
await _hubContext.Clients.All.SendAsync("notification", response.Data);
}
正如您在上面看到的,即使客户端已连接,
_hubContext.Clients.All
也是空的,因此它不会发送任何客户端。
在我的 Blazor 应用程序中,
Index.razor
:
@code {
string url = "http://localhost:1580/notificationhub";
HubConnection _connection = null;
bool isConnected = false;
string connectionStatus = "Ready";
private async Task ConnectToServer()
{
_connection = new HubConnectionBuilder()
.WithUrl(url)
.Build();
await _connection.StartAsync();
isConnected = true;
connectionStatus = "Connected";
_connection.Closed += async (s) =>
{
isConnected = false;
connectionStatus = "Disconnected";
await _connection.StartAsync();
isConnected = true;
};
_connection.On<string>("notification", m =>
{
connectionStatus = "I have data!";
StateHasChanged();
});
}
}
当我的
HubContext
注入控制器时,它可以工作,但是当它在常规类中时,它不起作用,因为clients.All
是空的。我该如何解决这个问题?
更新:
我想,我发现了问题所在。在我的安装程序中,我从 GeneralStockMarketHandler 类创建一个实例,并调用 StartToSubscribeAllStocksFromDb 方法。我必须一开始就调用一次这个方法
services.AddScoped<IGeneralStockMarketHandler, GeneralStockMarketHandler>();
var serviceProvider = services.BuildServiceProvider();
var stockMarketHandler serviceProvider.GetRequiredService<IGeneralStockMarketHandler>();
stockMarketHandler.StartToSubscribeAllStocksFromDb();
如果我不从 GeneralStockMarketHandler 类创建实例,那么我可以获得连接的客户端。
我不明白为什么它会影响逻辑。它不是单例,我只使用了一次
我也遇到这个问题了。在我看来,解决方案是定义一个名为 HubClientInfo 的类,并将其作为 Singleton 添加到方法中的项目服务中 该类定义如下::
public interface IHubClientInfo
{
List<IClientProxy> Clients { set; get; }
void Add(IClientProxy Client);
void Remove(IClientProxy Client);
}
在我的hub中,我注入了这个类的服务,在OnConnectedAsync方法中,我调用了我的类的Add方法,在OnDisconnectedAsync方法中,我调用了我的类的Remove方法。最后,无论我需要向客户端广播消息,我都会注入 HubClientInfo 服务并以这种方式发送消息。
foreach(var Client in _HubClientInfo.Clients)
await Client.SendAsync("SendMessage", "a", "b");