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

Unity中SignalR客户端编辑器正常,Android IL2CPP构建连接失败

Unity IL2CPP构建Android时SignalR HubConnection初始化失败问题

我在Unity中使用SignalR客户端开发实时Android游戏,Unity编辑器内运行一切正常,但切换为IL2CPP脚本后端构建Android版本后,无法连接到Hub服务器。通过adb logcat调试发现,HubConnectionBuilder.Build()方法执行时抛出类型初始化异常,代码及错误信息如下:

异常触发代码

connection = new HubConnectionBuilder()
        .WithUrl(ApiNeed.UrlNeed + "/game", opts =>
        {
            opts.HttpMessageHandlerFactory = (message) =>
            {
                if (message is HttpClientHandler clientHandler)
                    // 跳过SSL证书验证
                    clientHandler.ServerCertificateCustomValidationCallback +=
                        (sender, certificate, chain, sslPolicyErrors) => { return true; };
                return message;
            };
            opts.CloseTimeout = new TimeSpan(0, 5, 0);
            if (Token.ToLower().StartsWith("bearer"))
            {
                Token = Token.Substring("bearer".Length);
            }
            opts.Headers.Add("Authorization", Token);
        }
        )
        .Build(); // 异常发生处

捕获到的异常信息

The type initializer for 'Microsoft.AspNetCore.SignalR.Client.HubConnection' threw an exception.
myQm: at System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object[] parameters, System.Boolean wrapExceptions) [0x00000] in <00000000000000000000000000000000>:0
myQm: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor (Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite constructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext context) [0x00000] in <00000000000000000000000000000000>:0
myQm: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2[TArgument,TResult].VisitCallSiteMain (Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite callSite, TArgument argument) [0x00000] in <00000000000000000000000000000000>

补充说明:切换为Mono脚本后端构建时功能正常,但Mono无法生成x64/ARM64架构APK,且谷歌会提示应用不安全,因此必须使用IL2CPP后端。


可能的解决方法

1. 匹配SignalR客户端与IL2CPP兼容版本

IL2CPP对反射、动态代码支持有限,高版本SignalR可能存在兼容性问题:

  • 降级SignalR客户端到5.0.x或6.0.x稳定版,避免使用7.x及以上预览/新版本
  • 通过NuGet安装时,选择与当前Unity版本适配的包,优先选长期支持版

2. 配置IL2CPP链接器规则

IL2CPP链接器会自动剔除未被直接引用的代码,导致SignalR内部依赖服务无法初始化:

  • 在Assets/目录下创建link.xml文件,添加以下规则保留必要程序集:
<linker>
  <assembly fullname="Microsoft.AspNetCore.SignalR.Client" preserve="all" />
  <assembly fullname="Microsoft.Extensions.DependencyInjection" preserve="all" />
  <assembly fullname="System.Net.Http" preserve="all" />
  <assembly fullname="System.Threading.Tasks.Extensions" preserve="all" />
  <assembly fullname="Microsoft.AspNetCore.SignalR.Common" preserve="all" />
</linker>

3. 调整SSL证书验证逻辑

原代码中的匿名委托在IL2CPP下可能因序列化问题报错:

  • 若SignalR版本支持,直接使用SkipCertificateValidation快捷选项替代回调:
.WithUrl(ApiNeed.UrlNeed + "/game", opts =>
{
    opts.SkipCertificateValidation = true;
    // 其他配置...
})
  • 版本不支持时,改用静态方法替代匿名委托:
private static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    return true;
}

// 配置中调用静态方法
opts.HttpMessageHandlerFactory = (message) =>
{
    if (message is HttpClientHandler clientHandler)
        clientHandler.ServerCertificateCustomValidationCallback = ValidateCertificate;
    return message;
};

4. 修正Authorization头处理

原代码移除Bearer前缀可能导致认证失败,且字符串处理可能存在隐式问题:

if (Token.ToLower().StartsWith("bearer"))
{
    Token = Token.Substring("bearer".Length).Trim();
}
// 标准认证头格式需包含Bearer前缀
opts.Headers.Add("Authorization", $"Bearer {Token}");

5. 启用IL2CPP调试日志

开启调试选项获取更精准的错误定位:

  • 进入Edit > Project Settings > Player > Android > Publishing Settings
  • 勾选Development Build和Script Debugging
  • 构建后再次通过adb logcat捕获完整异常堆栈,定位具体缺失的类型或方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 19:30:56