赞
踩
WebSocket 大家都不陌生了,我们今天来看看怎么在Flutter中使用WebSocket!
web_socket_channel: ^2.2.0
我们使用 WebSocket库来进行WebSocket的相关操作
使用该库的连接方法为以下方式
IOWebSocketChannel ioWebSocketChannel = IOWebSocketChannel.connect("ws://ip:端口/ws");
连接成功后,我们下一步就是进行监听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; } } }
至此笔记到此结束,感谢你的观看!
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。