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

Unity并发调用API偶发HTTP协议错误问题排查求助

问题:Unity并发调用API时出现ProtocolError

我开发的Unity应用有三个功能按钮,分别对应调用API 1、API 2、API 3。连续快速点击按钮(近乎并发调用)时,偶尔会触发UnityWebRequest.Result.ProtocolError错误,想排查问题根源并找到修复方案。


Unity端API调用代码

// 按钮1、2、3的API调用逻辑如下
public IEnumerator APICall()
{
    using (UnityWebRequest uwr = UnityWebRequest.Get(URL))
    {
        uwr.SetRequestHeader("Content-Type", "application/json");

        uwr.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.Default.GetBytes(jsondata));

        yield return uwr.SendWebRequest();

        switch (uwr.result)
        {
            case UnityWebRequest.Result.ConnectionError:
                Debug.LogError(uwr.error);
                break;
            case UnityWebRequest.Result.DataProcessingError:
                Debug.LogError(uwr.error);
                break;
            case UnityWebRequest.Result.ProtocolError:
                Debug.LogError(uwr.error);
                break;
            case UnityWebRequest.Result.Success:
                Debug.Log(uwr.downloadHandler.text);
                // 业务处理逻辑
                Handling();
                break;
        }

    }
}

后端API代码

DBRepo.cs

public static class DBRepo
{
    static DBEntities db = new DBEntities();

    // 使用Entity Framework操作数据库

    public static void Add()
    {            
    }

    public static void Update()
    {            
    }

    public static void Delete()
    {            
    }

}

API1Controller.cs(插入数据)

public class API1Controller: ApiController
{
     public IHttpActionResult Get(string id, string status, [FromBody] data)
     {
          Calculation(); // 插入数据库前有复杂计算逻辑
          DBRepo.Add();
          // 返回响应
     }
}

API2Controller.cs(更新数据)

public class API2Controller: ApiController
{
     public IHttpActionResult Get(string id)
     {
          DBRepo.Update();
          // 返回响应
     }
}

API3Controller.cs(删除数据)

public class API3Controller: ApiController
{
     public IHttpActionResult Get(string id)
     {
          DBRepo.Delete();
          // 返回响应
     }
}

排查方向与修复建议

1. 后端线程安全问题(核心嫌疑)

DBRepo是静态类,且持有静态的DBEntities实例。Entity Framework的DbContext本身不支持线程安全,并发请求会共享这个静态实例,导致数据库操作冲突,最终返回5xx或4xx协议错误。

  • 修复:将DBEntities实例化移到每个方法内部,避免静态共享:
    public static class DBRepo
    {
        public static void Add()
        {            
            using (var db = new DBEntities())
            {
                // 执行插入逻辑
            }
        }
    
        // Update、Delete方法同理,每个方法内创建独立的DbContext
    }
    

2. Unity端调用逻辑问题

  • 你用UnityWebRequest.Get却设置了uploadHandler,这不符合HTTP规范:GET请求通常不携带请求体,后端可能因解析失败返回4xx错误。
    • 修复:根据API功能选择正确的HTTP方法,比如插入用Post、更新用Put、删除用Delete,而非统一用Get。
  • 并发请求节流:Unity默认HTTP并发连接数有限,快速点击可能导致请求排队超时。可添加请求限制,同一时间只允许一个API请求执行:
    private bool isRequesting = false;
    
    public void OnButtonClick()
    {
        if (isRequesting) return;
        StartCoroutine(APICallCoroutine());
    }
    
    private IEnumerator APICallCoroutine()
    {
        isRequesting = true;
        yield return APICall();
        isRequesting = false;
    }
    

3. 后端异常处理缺失

后端控制器方法没有异常捕获逻辑,复杂计算或数据库操作出错时,会直接抛出未处理异常,返回500内部服务器错误,对应Unity的ProtocolError。

  • 修复:在控制器方法中添加try-catch,返回友好错误响应:
    public IHttpActionResult Get(string id, string status, [FromBody] data)
    {
         try
         {
              Calculation();
              DBRepo.Add();
              return Ok("操作成功");
         }
         catch (Exception ex)
         {
              // 记录错误日志
              return InternalServerError(ex);
         }
    }
    

4. 网络层面排查

  • 查看uwr.error的具体信息,比如是400(请求格式错误)、404(资源不存在)还是500(服务器内部错误),直接定位问题类型。
  • 用Postman模拟并发请求,若能复现错误,说明问题在后端;若仅Unity出现,再排查Unity请求逻辑细节。

内容的提问来源于stack exchange,提问作者a_moss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:13:24