Blazor Server应用如何记录WebSocket Circuit消息为JSON格式到服务端控制台
实现Blazor Server Circuit消息JSON格式日志的方案
可以实现,不需要自定义WebSocket中间件,直接通过Blazor内置的CircuitHandler钩子 + 调整SignalR序列化配置即可完成需求。
步骤1:调整配置(可选,按需选择)
Blazor Server底层基于SignalR实现通信,默认使用MessagePack序列化传输消息,如果你不需要修改实际传输格式,仅需要日志输出为JSON,可以跳过这一步,直接在日志逻辑里做一次MessagePack转JSON即可。
如果希望传输本身也使用JSON格式,直接在Program.cs中修改SignalR配置:
builder.Services.AddServerSideBlazor() .AddHubOptions(options => { // 替换默认MessagePack序列化器为JSON序列化器 options.Serializer = new JsonHubProtocol(); });
步骤2:实现自定义CircuitHandler拦截消息
Blazor官方提供了CircuitHandler抽象类,专门用于监听Circuit生命周期、消息收发事件,无需手动hook底层WebSocket连接:
public class LoggingCircuitHandler : CircuitHandler { private readonly ILogger<LoggingCircuitHandler> _logger; public LoggingCircuitHandler(ILogger<LoggingCircuitHandler> logger) { _logger = logger; // 设置最高优先级,确保消息先被当前处理器拦截 Order = int.MaxValue; } // 记录服务端发往客户端的消息 public override Task OnSendMessageAsync(Circuit circuit, string messageId, string messageType, object[] args, CancellationToken cancellationToken) { var logContent = JsonSerializer.Serialize(new { CircuitId = circuit.Id, Direction = "Server->Client", MessageId = messageId, MessageType = messageType, Payload = args }, new JsonSerializerOptions { WriteIndented = true }); _logger.LogInformation("Circuit消息:\n{LogContent}", logContent); return base.OnSendMessageAsync(circuit, messageId, messageType, args, cancellationToken); } // 记录客户端发往服务端的消息 public override Task OnInvokeAsync(Circuit circuit, string invocationId, string methodName, object[] args, CancellationToken cancellationToken) { var logContent = JsonSerializer.Serialize(new { CircuitId = circuit.Id, Direction = "Client->Server", InvocationId = invocationId, MethodName = methodName, Payload = args }, new JsonSerializerOptions { WriteIndented = true }); _logger.LogInformation("Circuit消息:\n{LogContent}", logContent); return base.OnInvokeAsync(circuit, invocationId, methodName, args, cancellationToken); } // 可选:记录Circuit连接/断开事件 public override Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken) { _logger.LogInformation("Circuit {CircuitId} 已建立连接", circuit.Id); return base.OnConnectionUpAsync(circuit, cancellationToken); } public override Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken) { _logger.LogInformation("Circuit {CircuitId} 已断开连接", circuit.Id); return base.OnConnectionDownAsync(circuit, cancellationToken); } }
步骤3:注册服务到依赖注入容器
在Program.cs中添加自定义处理器的注册即可生效:
builder.Services.AddSingleton<CircuitHandler, LoggingCircuitHandler>();
注意事项
- 生产环境建议关闭全量消息日志,避免占用过多IO资源、泄露用户敏感操作信息
- 保留msgpack传输仅日志转JSON的场景下,直接在日志方法中添加MessagePack反序列化为对象再转JSON的逻辑即可,不影响传输性能
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

