我们正在评估如何通过 SignalR 向连接的客户端发送消息。我们的应用程序在 Azure 中发布,并且有多个实例。我们能够成功地将消息传递给连接到同一实例的客户端,而不是其他实例。
我们最初关注的是 ServiceBus,但我们(可能是错误地)发现 AzureSignalR 基本上应该是一个为我们处理所有后端内容的服务总线。
我们在 Startup.cs 中设置 signalR 如:
public void ConfigureServices(IServiceCollection services)
{
var signalRConnString = Configuration.GetConnectionString("AxiomSignalRPrimaryEndPoint");
services.AddSignalR()
.AddAzureSignalR(signalRConnString)
.AddJsonProtocol(options =>
{
options.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAzureSignalR(routes =>
{
routes.MapHub<CallRegistrationHub>("/callRegistrationHub");
routes.MapHub<CaseHeaderHub>("/caseHeaderHub");
routes.MapHub<EmployeesHub>("/employeesHub");
});
}
问题
我们必须存储一些可能应该在服务总线上的对象,而不是存储在单个实例中;但是,我不确定如何告诉集线器对象应该在总线上,而不是在集线器的特定实例内部,如下所示:
public class EmployeesHub : Hub
{
private static volatile List<Tuple<string, string, string,string, int>> UpdateList = new List<Tuple<string, string, string,string,int>>();
private static volatile List<Tuple<string, int>> ConnectedClients = new List<Tuple<string, int>>();
}
我们有一些函数需要向所有正在查看当前记录的已连接客户端发送消息,无论它们位于什么实例中:
public async void LockField(string fieldName, string value, string userName, int IdRec)
{
var clients = ConnectedClients.Where(x => x.Item1 != Context.ConnectionId && x.Item2 == IdRec).Select(x => x.Item1).Distinct().ToList();
clients.ForEach(async x =>
{
await Clients.Client(x).SendAsync("LockField", fieldName, value, userName, true);
});
if (!UpdateList.Any(x=> x.Item1 == Context.ConnectionId && x.Item3 == fieldName && x.Item5 == IdRec))
{
UpdateList.Add(new Tuple<string, string, string,string,int>(Context.ConnectionId,userName, fieldName, value, IdRec));
}
}
这不适用于不同的实例(这是有道理的,因为每个实例都有自己的对象。但是,我们希望通过使用 AzureSignalR 而不是 SignalR(AzureSignalR conn 字符串具有 Azure 服务的端点),它将处理为我们提供服务总线功能。我们不确定要采取哪些步骤才能使其正常运行。
谢谢。