You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 14:17:32