• Flutter学习笔记 —— WebSocket篇


    Flutter学习笔记 —— WebSocket

    在这里插入图片描述

    前言

    WebSocket 大家都不陌生了,我们今天来看看怎么在Flutter中使用WebSocket!

    开发环境

    • Android Studio
    • Android SDK API 33

    Flutter 安装插件

    web_socket_channel: ^2.2.0
    

    正文

    我们使用 WebSocket库来进行WebSocket的相关操作

    一、连接

    使用该库的连接方法为以下方式

    IOWebSocketChannel ioWebSocketChannel = IOWebSocketChannel.connect("ws://ip:端口/ws");
    

    连接成功后,我们下一步就是进行监听Socket消息

    ListenerStream(监听Socket消息)

    以下是监听Socket消息方式

    ioWebSocketChannel.stream.listen((data){
        //消息
    }));
    

    值得一提的是监听方式不但可以监听消息,还可以监听异常和Socket连接是否结束

    以下是代码示例

    ioWebSocketChannel.stream.listen((event) { 
             
           },onDone: (){
             //结束!
           },onError: (){
             //异常!
        });
    

    我们知道,当Socket服务一定时间内没收到消息则会认为超时,那么我们应该发送心跳包,接下来会逐步介绍

    SendMessage(发送Socket消息)
    

    发送Socket消息也非常简单,请看代码示例

    ioWebSocketChannel.sink.add("消息");
    

    add(T) 可以发送的消息是一个泛型,意味着你可以发送不同的消息至服务器

    四、发送心跳包

    什么是心跳包呢?简述概括就是:

    当Socket服务一定时间没有收到消息则会自动断连,那么此时我们要做的就是一定时间内发送心跳消息至Socket服务,让服务认为客户端还活着,从而继续工作!

    我们从中可以得到一些关键字的消息

    一定时间发送消息至服务器

    第一时间我们想到的就是定时器(Timer) 当然如果你想用Future的延迟也是可以的!

    说了那么多,我们看看如何实现!

    定义计时器方法

      /**
       * 发送心跳包
       */
      static void sendHeartPacket(){
        Map<String,dynamic> data = {
          "code": 9999,
          "msg": "心跳包",
        };
        var jsonData = json.encode(data);
        IOWebSocketChannel.sink.add(jsonData);
      }
    

    我们定义了一个基础的发包方法,那我们接下来需要处理的就是,在一定时间内发心跳包到服务器,如果心跳包发成功了,那么我们应该重新连接

    发送心跳包

      /**
       * @desc WebSocket心跳包
       * @author Marinda
       * @date 2022/9/26
       */
      static void heartPacket(){
    
          //自定义Bool,判断是否Socket开启状态
         if(state.socketStatus){
    
          //自定义重连时间间隔
           hearTimer = Timer(Duration(seconds: state.socketClienTime),() async{
           //  重新连接
             reconnectSocket();
           });
           sendHeartPacket();
         }
      }
    
    

    断开连接

      /**
       * 销毁心跳包
       */
      static void destoryHeart(){
         //为心跳包则直接
         if(state.heartStatus){
            hearTimer?.cancel();
            state.heartStatus = false;
         }
      }
    

    重新连接

      /**
       * 重新连接socket
       */
      static void reconnectSocket(){
         destoryHeart();
         connectSocket();
      }
    

    代码示例

    import 'dart:async';
    import 'package:dio/dio.dart';
    import 'package:web_socket_channel/io.dart';
    import 'package:web_socket_channel/web_socket_channel.dart';
    import 'State.dart';
    import 'dart:convert';
    
    import 'Result.dart';
    /**
     * @date 2022/9/26
     * @author Marinda
     * @desc websocket的实现
     */
    class WebSocketHandle {
      static WebSocketState state = WebSocketState();
      static late Timer hearTimer;
      WebSocketHandle();
    
       static void connectSocket() async {
           await closeSocket();
           String socketUrl = state.socketUrl;
           LoggerUtil.logger.i("发起WebSocket请求,地址为:${socketUrl}");
           state.webSocket = IOWebSocketChannel.connect(socketUrl);
    
           state.socketStatus = true;
           initConnectSocket();
      }
    
      static void initConnectSocket(){
        WebSocketHandle.onMessageListener();
        heartPacket();
      }
    
      /**
       * @desc 校验连接配置是否重复
       * @author Marinda
       * @date 2022/9/27
       */
      static bool validConnection(String ip,int port){
         return state.ip == ip && state.port == port ? true : false;
      }
      /**
       * @desc WebSocket消息监听器
       * @author Marinda
       * @date 2022/9/26
       */
      static void onMessageListener(){
    
         WebSocketResult webSocketResult = WebSocketResult();
         state.webSocket?.stream.listen((data){
          var jsonData = json.decode(data);
          if(jsonData is Map<String,dynamic>){
            //检测到心跳包
            if(jsonData['code'] == 9999){
            //  不处理
            }else{
              Map<String,dynamic> mapData = jsonData['data'];
              webSocketResult = WebSocketResult.fromJson(mapData);
                state.webSocketResult = webSocketResult;
                LoggerUtil.logger.i("监听到服务端Socket返回数据:                   ${state.webSocketResult.toString()}");   
    },onError: (e){
          state.socketStatus = false;
          state.isError = true;
        },onDone: (){
          state.socketStatus = false;
        });
      }
    
      /**
       * 销毁心跳包
       */
      static void destoryHeart(){
         //为心跳包则直接
         if(state.heartStatus){
            hearTimer?.cancel();
            state.heartStatus = false;
         }
      }
    
      /**
       * 发送心跳包
       */
      static void sendHeartPacket(){
        Map<String,dynamic> data = {
          "code": 9999,
          "msg": "心跳包",
        };
        var jsonData = json.encode(data);
        state.webSocket?.sink.add(jsonData);
        state.heartStatus = true;
      }
    
      /**
       * @desc WebSocket心跳包
       * @author Marinda
       * @date 2022/9/26
       */
      static void heartPacket(){
         if(state.socketStatus){
           hearTimer = Timer(Duration(seconds: state.socketClienTime),() async{
           //  重新连接
             reconnectSocket();
           });
           sendHeartPacket();
         }
      }
    
      /**
       * 重新连接socket
       */
      static void reconnectSocket(){
         destoryHeart();
         connectSocket();
      }
    
      /**
       * @desc 关闭WebSocket
       * @author Marinda
       * @date 2022/9/26
       */
      static Future closeSocket() async{
         if(state.webSocket != null){
           state.webSocket?.sink.close();
           state.webSocket = null;
           state.socketStatus = false;
         }
      }
    
    }
    

    结束

    至此笔记到此结束,感谢你的观看!

  • 相关阅读:
    目标检测YOLO实战应用案例100讲-基于改进YOLOv4算法的自动驾驶场景 目标检测
    嵌入式Linux应用开发基础知识(四)——Makefile语法
    【微信小程序】使用uni-app——开发首页搜索框导航栏(可同时兼容APP、H5、小程序)
    Linux下安装cx_Oracle,连接oracle数据库
    ARM系列之ARM多核指令WFE、WFI、SEV原理
    断网重连里面的长连接,短链接和心跳机制
    信息学奥赛一本通 1435:【例题3】曲线 | 洛谷 洛谷 P1883 函数
    CentOS 7安装zookeeper
    u盘文件突然不见了如何找回呢?
    浅谈IT隔离电源系统在医疗场所的接地设计研究与应用
  • 原文地址:https://blog.csdn.net/qq_33638188/article/details/127106389