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

Azure Function App调用SignalR时出现SocketException异常如何排查修复

问题诱因
  • 安卓端HTTP客户端默认配置与系统策略差异:Xamarin.Forms安卓端默认使用的AndroidClientHandler超时阈值设置较低(通常默认15s),且安卓系统电池优化策略会主动中止后台应用的网络线程,当Function内部SignalR操作偶发耗时超过阈值时,安卓端会主动断开TCP连接,导致Function端请求上下文被取消,触发signalRGroupActions.AddAsync()抛出中断异常。iOS端的NSUrlSession默认超时更长、后台网络限制逻辑更宽松,因此无异常。
  • Azure Function SignalR输出绑定的默认批处理逻辑延迟:IAsyncCollector默认会攒批提交操作到SignalR服务,当Function实例负载较高、Azure SignalR服务出现临时限流或网络波动时,批处理提交耗时偶发变长,超过请求取消阈值触发异常。
  • 旧版本Xamarin安卓网络栈已知BUG:低于5.0版本的Xamarin.Forms、低于1.7版本的Xamarin.Essentials存在TCP连接池复用错误,会偶发提前断开活跃请求连接,该问题仅在安卓端存在。
修复方案
  • 调整安卓端HTTP客户端配置
    显式配置全局HttpClient的超时时间与实现,避免默认激进的中断逻辑,示例配置代码:
    // 安卓项目MainActivity.OnCreate方法中添加
    var handler = new AndroidClientHandler
    {
        ConnectTimeout = TimeSpan.FromSeconds(30),
        ReadTimeout = TimeSpan.FromSeconds(30),
        AutomaticDecompression = System.Net.DecompressionMethods.GZip
    };
    // 全局复用该HttpClient实例发起请求,避免重复创建连接
    App.HttpClient = new HttpClient(handler);
    
    同时引导用户将应用添加到安卓系统的电池优化白名单,避免后台网络请求被系统强制中止。
  • 优化Azure Function代码逻辑
    新增取消令牌参数支持,主动刷新SignalR操作提交避免攒批延迟,同时提前返回响应减少客户端等待时间,修改后代码如下:
    [FunctionName(nameof(LeaveGroup))]
    public static async Task LeaveGroup(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "LeaveGroup/{userId}")] HttpRequest req,
        string userId,
        [SignalR(HubName = "webrtchub")] IAsyncCollector<SignalRGroupAction> signalRGroupActions,
        CancellationToken cancellationToken,
        ILogger log)
    {
        try
        {
            await signalRGroupActions.AddAsync(
                new SignalRGroupAction
                {
                    UserId = userId,
                    Action = GroupAction.RemoveAll
                }, cancellationToken);
            // 主动刷新立刻提交操作,避免默认攒批延迟
            await signalRGroupActions.FlushAsync(cancellationToken);
            
            // 提前返回响应,减少客户端等待时间
            req.HttpContext.Response.StatusCode = 200;
            await req.HttpContext.Response.CompleteAsync();
            
            log.LogInformation($"Trigger function removed {userId} from all groups");
        }
        catch (TaskCanceledException ex) when (!cancellationToken.IsCancellationRequested)
        {
            // 针对SignalR侧的超时添加3次指数退避重试
            for (int i = 0; i < 3; i++)
            {
                await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i)), cancellationToken);
                try
                {
                    await signalRGroupActions.AddAsync(new SignalRGroupAction
                    {
                        UserId = userId,
                        Action = GroupAction.RemoveAll
                    }, cancellationToken);
                    await signalRGroupActions.FlushAsync(cancellationToken);
                    req.HttpContext.Response.StatusCode = 200;
                    await req.HttpContext.Response.CompleteAsync();
                    return;
                }
                catch
                {
                    if (i == 2) throw;
                }
            }
        }
    }
    
  • 升级依赖组件版本
    将Xamarin.Forms、Xamarin.Essentials升级到最新稳定版,安卓项目目标框架升级到Android 12及以上,修复原生网络栈的已知BUG。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 20:18:03