RestSharp请求中途对方断网无响应,如何使其及时触发反应?
解决RestSharp在Android断网时无响应的问题
你的场景是:Android应用用RestSharp调用REST API,中途切断Wi-Fi后RestSharp无反应,恢复网络后也无法接收响应,最终超时。以下是针对性的解决方案:
现有代码的核心问题
- 空catch块吞掉所有异常:
catch {}会吃掉网络中断、连接失败等所有异常,导致你看不到任何错误提示。 - 同步请求无法主动取消:使用同步
Execute方法,无法在断网时主动终止请求,只能等待整体超时。 - TCP连接检测不及时:默认TCP参数下,断网后不会立即检测到连接失效,需要等待较长时间才会触发超时。
- 请求体序列化错误:用
body.ToString()传递请求体,大概率不是正确的JSON格式,可能导致服务端无法解析,但这不是当前断网问题的核心。
具体修复方案
1. 修复异常捕获,不再吞掉错误
移除空catch块,针对性捕获网络相关异常,至少记录错误信息,方便排查问题:
catch (IOException ex) { // 处理网络异常(断网、连接失败等) Log.Error("RestSharp", $"Network error: {ex.Message}"); } catch (OperationCanceledException) { // 处理请求被主动取消的情况 Log.Info("RestSharp", "Request canceled due to network loss"); } catch (Exception ex) { // 处理其他异常 Log.Error("RestSharp", $"Unexpected error: {ex.Message}"); }
2. 改用异步请求并支持主动取消
Android禁止在主线程执行同步网络请求,且异步请求配合CancellationToken可以在断网时主动终止请求:
private CancellationTokenSource _requestCts; public async Task<AndroidSmartPOSDeviceResponse> PaymentAsync(string orderId, double amount) { _requestCts = new CancellationTokenSource(); RestResponse response = null; try { var request = new RestRequest("/v1/transactions/payment", Method.Post); request.AddHeader("X-SOURCE", "PaymentSystem"); var body = new AndroidSmartPOSRequest { orderId = orderId, amount = amount }; // 用RestSharp内置的AddJsonBody自动序列化JSON,替代手动ToString request.AddJsonBody(body); // 传入取消令牌,支持主动终止请求 response = await client.ExecuteAsync(request, _requestCts.Token); } catch (IOException ex) { Log.Error("RestSharp", $"Network error: {ex.Message}"); } catch (OperationCanceledException) { Log.Info("RestSharp", "Request canceled"); } catch (Exception ex) { Log.Error("RestSharp", $"Error: {ex.Message}"); } finally { _requestCts.Dispose(); _requestCts = null; } return response?.Content != null ? JsonSerializer.Deserialize<AndroidSmartPOSDeviceResponse>(response.Content) : null; }
3. 配置TCP KeepAlive,加快断网检测
RestSharp在Android底层使用OkHttp,通过配置TCP KeepAlive参数,让连接更快检测到网络断开:
public RestInterface(string ip, string port) { var baseUrl = $"https://{ip}:{port}/"; var options = new RestClientOptions(baseUrl) { MaxTimeout = 280 * 1000, RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true, ThrowOnAnyError = true }; // 配置OkHttp的TCP KeepAlive参数 options.ConfigureMessageHandler = handler => { if (handler is OkHttpMessageHandler okHttpHandler) { var newClient = okHttpHandler.OkHttpClient.NewBuilder() .KeepAliveDuration(5, TimeUnit.Seconds) // 每5秒发送一次心跳包 .Build(); okHttpHandler.OkHttpClient = newClient; } return handler; }; client = new RestClient(options); }
4. 监听Android网络状态,断网时主动取消请求
通过Android的ConnectivityManager监听网络变化,当网络断开时立即取消当前请求:
// 在Activity/Service中注册网络监听 private ConnectivityManager _connectivityManager; private NetworkCallback _networkCallback; private void InitNetworkListener() { _connectivityManager = (ConnectivityManager)GetSystemService(Context.ConnectivityService); _networkCallback = new NetworkCallback(this); var networkRequest = new NetworkRequest.Builder() .AddTransportType(TransportType.Wifi) .AddTransportType(TransportType.Cellular) .Build(); _connectivityManager.RegisterNetworkCallback(networkRequest, _networkCallback); } // 自定义网络回调类 private class NetworkCallback : ConnectivityManager.NetworkCallback { private readonly YourActivity _activity; public NetworkCallback(YourActivity activity) { _activity = activity; } public override void OnLost(Network network) { base.OnLost(network); // 网络断开时取消当前RestSharp请求 _activity._restInterface?._requestCts?.Cancel(); } } // 在页面销毁时注销监听 protected override void OnDestroy() { base.OnDestroy(); _connectivityManager?.UnregisterNetworkCallback(_networkCallback); }
关键说明
- TCP KeepAlive:通过定期发送心跳包,让系统更快检测到连接失效,避免长时间等待超时。
- 异步请求:避免阻塞UI线程,同时支持主动取消,提升用户体验。
- 网络监听:主动感知网络状态变化,及时终止无效请求,而不是被动等待超时。
内容的提问来源于stack exchange,提问作者Lechucico
相关产品推荐
相关产品推荐

