SignalR是一个开源的.NET库,用于构建实时Web应用程序。它简化了在客户端和服务器之间添加实时Web功能的过程,支持服务器向连接的客户端主动推送内容。
[Web App 1] ←→ [SignalR Backplane (如Redis)] ←→ [Web App 2]
// Startup.cs或Program.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR()
.AddStackExchangeRedis("localhost:6379", options => {
options.Configuration.ChannelPrefix = "MyApp_";
});
}
public class CommunicationHub : Hub
{
public async Task SendMessageToAllApps(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
public async Task JoinGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
public async Task SendMessageToGroup(string groupName, string message)
{
await Clients.Group(groupName).SendAsync("ReceiveGroupMessage", message);
}
}
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<CommunicationHub>("/communicationHub");
});
const connection = new signalR.HubConnectionBuilder()
.withUrl("/communicationHub")
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on("ReceiveMessage", (user, message) => {
console.log(`${user}: ${message}`);
});
connection.on("ReceiveGroupMessage", (message) => {
console.log(`Group message: ${message}`);
});
async function start() {
try {
await connection.start();
console.log("SignalR Connected.");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
}
connection.onclose(async () => {
await start();
});
// 启动连接
start();
现象:客户端无法连接到SignalR端点 解决:确保CORS配置正确
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder =>
{
builder.WithOrigins("http://example.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
// 然后在Configure中
app.UseCors("CorsPolicy");
现象:消息无法在所有服务器实例间传播 解决:使用Redis或Azure SignalR服务作为背板
services.AddSignalR().AddStackExchangeRedis("redis_server:6379");
现象:连接频繁断开 解决:配置自动重连和保持活动
// 客户端
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.withAutomaticReconnect([0, 2000, 10000, 30000]) // 重试间隔
.build();
优化建议:
services.AddSignalR().AddMessagePackProtocol(options => {
options.SerializerOptions = MessagePackSerializerOptions.Standard
.WithCompression(MessagePackCompression.Lz4BlockArray);
});
public class CommunicationHub : Hub
{
private readonly string _tenantId;
public CommunicationHub(IHttpContextAccessor httpContextAccessor)
{
_tenantId = httpContextAccessor.HttpContext.Request.Headers["X-Tenant-ID"];
}
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, _tenantId);
await base.OnConnectedAsync();
}
}
public class CustomHubFilter : IHubFilter
{
public async ValueTask<object> InvokeMethodAsync(
HubInvocationContext invocationContext,
Func<HubInvocationContext, ValueTask<object>> next)
{
// 检查权限等
return await next(invocationContext);
}
}
// 注册过滤器
services.AddSignalR(options => {
options.AddFilter<CustomHubFilter>();
});
SignalR为多Web应用间通信提供了强大而灵活的解决方案,特别适合需要实时交互和状态同步的场景。通过合理配置和优化,可以构建出高性能、可靠的跨应用通信系统。
没有搜到相关的文章