SignalR AspNetCore v1.0.0:直接使用Connection对象的替代方案咨询
.NET Core SignalR 替代原 PersistentConnection 的方案
我来帮你理清这个问题:ASP.NET Core SignalR 确实没有直接对应 .NET Framework SignalR里的PersistentConnection/Connection类——它的设计重心完全偏向了Hub模式,但你有两种可行的方式实现类似的底层功能:
1. 用 Hub 模拟原始连接行为(推荐方案)
虽然Core SignalR主推强类型Hub调用,但你可以在Hub里实现类似PersistentConnection的原始消息处理逻辑,完全不需要依赖特定的方法签名。
举个简单的示例:
public class RawMessageHub : Hub { // 接收客户端发来的任意原始消息 public async Task HandleRawMessage(string rawContent) { // 这里就像你之前在PersistentConnection里的OnReceived方法一样 // 可以解析消息、路由到不同业务逻辑,甚至广播给其他连接 await Clients.Caller.SendAsync("RawMessageResponse", $"Processed your message: {rawContent}"); } // 同样可以重写连接生命周期方法 public override async Task OnConnectedAsync() { var connectionId = Context.ConnectionId; // 比如记录连接建立日志、初始化连接相关状态 await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception? exception) { // 处理连接断开后的清理逻辑 await base.OnDisconnectedAsync(exception); } }
客户端这边,不管是.NET还是JS,都可以直接调用这个方法传递原始内容。比如.NET客户端:
var hubConnection = new HubConnectionBuilder() .WithUrl("http://yourserver/rawMessageHub") .Build(); // 注册接收服务器返回的原始响应 hubConnection.On<string>("RawMessageResponse", response => { Console.WriteLine(response); }); await hubConnection.StartAsync(); // 发送原始消息 await hubConnection.SendAsync("HandleRawMessage", "Hello from .NET Core client!");
如果你的客户端需要发送完全无结构的字节数据,也可以用Hub的SendAsync传递byte[]类型的参数,完全满足底层需求。
2. 自定义WebSocket中间件(极端底层场景)
如果你的需求完全脱离SignalR的协议封装,需要直接和客户端做原始WebSocket通信,那可以自己编写中间件来处理WebSocket请求——不过这种方式需要你自己实现连接管理、心跳、重连等SignalR已经帮你做好的功能,复杂度很高,只适合特殊场景。
示例代码参考:
app.Use(async (context, next) => { // 拦截指定路径的WebSocket请求 if (context.Request.Path == "/rawWebSocket" && context.WebSockets.IsWebSocketRequest) { using var webSocket = await context.WebSockets.AcceptWebSocketAsync(); var buffer = new byte[4096]; WebSocketReceiveResult receiveResult; do { // 接收客户端的原始字节数据 receiveResult = await webSocket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None); // 处理接收到的数据,比如解析成字符串或自定义格式 var receivedMessage = Encoding.UTF8.GetString(buffer, 0, receiveResult.Count); var response = Encoding.UTF8.GetBytes($"Server received: {receivedMessage}"); // 发送响应给客户端 await webSocket.SendAsync( new ArraySegment<byte>(response, 0, response.Length), receiveResult.MessageType, receiveResult.EndOfMessage, CancellationToken.None); } while (!receiveResult.CloseStatus.HasValue); // 处理连接关闭 await webSocket.CloseAsync( receiveResult.CloseStatus.Value, receiveResult.CloseStatusDescription, CancellationToken.None); return; } // 不是WebSocket请求,交给后续中间件处理 await next(); });
补充:为什么Core SignalR移除了PersistentConnection?
ASP.NET Core SignalR是完全重写的版本,团队选择聚焦Hub模式,因为它提供了更简洁的API,同时内置了分组、用户关联、强类型调用等实用功能——大多数原本用PersistentConnection的场景,都可以通过Hub灵活实现,没必要保留两套API增加复杂度。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

