当前位置:   article > 正文

Flutter学习笔记 —— WebSocket篇_flutter websocket

flutter websocket

Flutter学习笔记 —— WebSocket篇

在这里插入图片描述

前言

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

开发环境

  • Android Studio
  • Android SDK API 33

Flutter 安装插件

web_socket_channel: ^2.2.0
  • 1

正文

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

一、连接

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

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

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

ListenerStream(监听Socket消息)

以下是监听Socket消息方式

ioWebSocketChannel.stream.listen((data){
    //消息
}));
  • 1
  • 2
  • 3

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

以下是代码示例

ioWebSocketChannel.stream.listen((event) { 
         
       },onDone: (){
         //结束!
       },onError: (){
         //异常!
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

SendMessage(发送Socket消息)
  • 1

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

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

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);
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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

发送心跳包

  /**
   * @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();
     }
  }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

断开连接

  /**
   * 销毁心跳包
   */
  static void destoryHeart(){
     //为心跳包则直接
     if(state.heartStatus){
        hearTimer?.cancel();
        state.heartStatus = false;
     }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

重新连接

  /**
   * 重新连接socket
   */
  static void reconnectSocket(){
     destoryHeart();
     connectSocket();
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

代码示例

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;
     }
  }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129

结束

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/268662
推荐阅读
相关标签
  

闽ICP备14008679号