flutter——socket填坑

又是填坑的一天

背景

突然有用户反馈,页面卡死,无法操作。这便是全部信息,让排查问题。排查过程是很困难的,直接说结论:前同事socket使用错误,导致内存占用过大,任何事件都得不到响应。

原代码

  • 环境
    flutter : 2.10.4
    dart : 2.16.2
    socket_io_client : 0.9.12
  • 原代码
class SocketIoUtil {
   
   
  static bool retryConnect = false;
  static var messDate;

  static Future socketIo() async {
   
   
    // print("创建isolate");
    retryConnect = true;
    onConnect();
  }

  static Future dispose() async {
   
   
    retryConnect = false;
    socket?.disconnect();
    socket = null;
    messDate = null;
    return null;
  }

  static Future onConnect() async {
   
   
	 print("socket:onConnect");
  	// 随便写的,具体连接是有逻辑判断的
  	String connectUrl="http://www.xxx.com:1414";
    socket = IO.io(
          connectUrl, IO.OptionBuilder().setTransports(['websocket']).build());
          
    socket.on(
          "message",
          (data) => {
   
   
                onMessage(data.toString()),
              });

    socket.onDisconnect((data) => {
   
   
            print("socket:连接断开"),
            _retryConnectSocketIo(),
          });
    socket.onConnect((data) => {
   
   
            print("socket:连接成功"),
          });
    socket.onConnectError((data) => {
   
   
            print("socket:连接出错"),
            _retryConnectSocketIo(),
          });
  }

  static onMessage(String string) {
   
   
    // do something
  }

  static _retryConnectSocketIo() {
   
   
    if (retryConnect) {
   
   
      print("socket:开启重新连接");
      Future.delayed(Duration(seconds: 10), () {
   
   
        onConnect();
      });
    }
  }
}

分析

大概逻辑就是开启一个socket,连接成功则对接收到的消息进行业务处理,否则10s后重试连接。
看似没啥问题,但实测后打印日志如下:
在这里插入图片描述

问题解决

1.1 解决过度重试

从原代码可以看出在连接失败后会调用_retryConnectSocketIo方法,而该方法会在延迟10s后调用 onConnect 方法,但日志中显示在这延迟的10s中又多调用了3次 连接出错 ,这样在下一个10s后就会总共调用 4个onConnect 方法,而每个onConnect又会调用4次 连接出错,那么再过10s就会有4*4个 onConnect被调用。这样每个10s就会有4倍的socket连接,最终导致内存占用过大,项目卡死。

然而这些多余的连接出错不是项目触发的,因此怀疑创建的socket自身具有失败重试的功能。因此对代码进行如下修改:

	...
 static Future onConnect() async {
   
   
	 print("socket:onConnect");
  	// 随便写的,具体连接是有逻辑判断的
  	String connectUrl="http://www.xxx.com:1414";
    socket = IO.io(
          connectUrl,
          IO.OptionBuilder()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

得食猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值