如何在Unity的WebSocket客户端中实现类似路由的功能?
Unity C# 实现WebSocket路由的常规方案
核心思路
和JavaScript的实现逻辑本质一致:先解析消息中的route字段,再通过路由映射匹配对应的处理方法。区别在于C#是强类型语言,需要针对性处理不同数据结构的反序列化问题。
步骤1:定义基础消息结构
先创建仅包含route字段的基础类,用来快速解析出路由标识:
public class BaseWebSocketMessage { public string route { get; set; } }
步骤2:定义各路由对应的具体数据结构
为每个路由创建对应的数据实体类,适配业务需求:
// 对应route_1的数据结构 public class Route1Data { public int id { get; set; } public string content { get; set; } } // 对应route_2的数据结构 public class Route2Data { public float value { get; set; } public bool isActive { get; set; } }
步骤3:构建路由映射字典
用字典存储路由名称与处理委托的映射,通过泛型委托适配不同数据类型:
// 定义通用处理委托 public delegate void WebSocketHandler<T>(T data); // 路由映射字典 private Dictionary<string, object> _routeHandlers = new Dictionary<string, object>(); // 初始化路由映射 private void InitWebSocketRoutes() { _routeHandlers.Add("route_1", new WebSocketHandler<Route1Data>(HandleRoute1)); _routeHandlers.Add("route_2", new WebSocketHandler<Route2Data>(HandleRoute2)); } // 具体路由处理方法 private void HandleRoute1(Route1Data data) { Debug.Log($"处理route_1:ID={data.id},内容={data.content}"); } private void HandleRoute2(Route2Data data) { Debug.Log($"处理route_2:数值={data.value},状态={data.isActive}"); }
步骤4:消息接收与路由分发
在WebSocket的消息回调中,先解析基础消息拿到route,再反序列化对应数据并执行处理方法:
// 以Unity原生WebSocket消息回调为例 private void OnWebSocketMessageReceived(string rawMessage) { // 第一步:解析基础消息获取路由标识 var baseMsg = JsonUtility.FromJson<BaseWebSocketMessage>(rawMessage); if (string.IsNullOrEmpty(baseMsg.route) || !_routeHandlers.ContainsKey(baseMsg.route)) { Debug.LogWarning($"未匹配到路由:{baseMsg.route}"); return; } // 第二步:根据路由分发消息 var handler = _routeHandlers[baseMsg.route]; switch (baseMsg.route) { case "route_1": var route1Data = JsonUtility.FromJson<Route1Data>(rawMessage); ((WebSocketHandler<Route1Data>)handler)(route1Data); break; case "route_2": var route2Data = JsonUtility.FromJson<Route2Data>(rawMessage); ((WebSocketHandler<Route2Data>)handler)(route2Data); break; // 新增路由时补充对应的case分支 } }
优化方案:消除switch-case冗余
如果路由数量较多,switch-case会变得繁琐,可通过反射实现通用分发逻辑:
private void DispatchWebSocketMessage(string rawMessage) { var baseMsg = JsonUtility.FromJson<BaseWebSocketMessage>(rawMessage); if (!_routeHandlers.TryGetValue(baseMsg.route, out var handler)) { Debug.LogWarning($"未找到路由处理逻辑:{baseMsg.route}"); return; } // 获取委托的泛型参数类型 var handlerType = handler.GetType(); var dataType = handlerType.GetGenericArguments()[0]; // 反序列化对应类型的数据 var data = JsonUtility.FromJson(rawMessage, dataType); // 调用处理方法 handlerType.GetMethod("Invoke")?.Invoke(handler, new[] { data }); }
注意事项
- 若使用Newtonsoft.Json(可通过Unity Package Manager导入),只需将
JsonUtility替换为JsonConvert,支持更复杂的JSON结构。 - 反射实现会有轻微性能开销,对性能要求极高的场景,建议保留switch-case或提前缓存类型信息。
- 可将路由逻辑抽成独立的
WebSocketRouter类,实现业务逻辑与路由分发的解耦。
内容的提问来源于stack exchange,提问作者IIITS TIIIMEEE
相关产品推荐
相关产品推荐

