uniapp websocket 封装断线重连

 1.新建一个工具类js文件

2. 把我封装的代码复制进去

//引入vuex,因为我需要使用vuex存储得到的数据
import store from "@/store/index.js"
// 连接
let socketTask = null
// 是否主动关闭连接
let meClose = false
// 地址 写你的后端连接地址
let url = "ws://192.168.1.2:8888/ws/"
let token = null
// 重连定时器
let Time = null
// 心跳定时器
let XTime = null
// 开启连接
const sokcet = () => {
    // 我这个项目需要在连接的时候带token,不需要可以只写url地址
	token = uni.getStorageSync("token") //token
	// console.log(url + token);
	//判断是否有websocet对象,有的话清空
	if (socketTask) {
		uni.closeSocket()
		socketTask = null;
	}
	// 进行连接
	socketTask = uni.connectSocket({
		url: url + token, //仅为示例,并非真实接口地址。不需要带token可以只写url地址
		success(data) {
			clearInterval(Time) //关闭定时器
			clearInterval(XTime) //关闭心跳定时器
			console.log("创建连接!");
			// 监听是否连接
			uni.onSocketOpen((res) => {
				console.log('连接成功!获取离线信息');
				sendMsg("1000")
				clearInterval(Time) //关闭定时器
				clearInterval(XTime) //关闭心跳定时器
				// 5秒发送一次心跳//后端检测是否在线
				XTime = setInterval(() => {
					// console.log("心跳");
					sendMsg("2000")
				}, 5000)
			});
		}
	});

	// 监听连接失败
	uni.onSocketError((err) => {
		console.log('连接失败,请检查');
		if (!meClose) {//判断是否主动关闭进行重新连接
			reconnect()
		}
	})
	// 监听连接关闭close
	uni.onSocketClose((e) => {
		console.log('连接关闭!', meClose);
		if (!meClose) {//判断是否主动关闭进行重新连接
			reconnect()
		}
	})
	// 监听收到信息
	uni.onSocketMessage((res) => {
		let data = JSON.parse(res.data)
		// 接收数据后回调
		console.log('服务器内容:', data);
        // 我存储数据到vuex
		// 全部消息列表
		// store.commit("login/pushList", data)
		// 提醒消息列表 
		// store.commit("login/unshiftMessage", data)
		// 存储到本地
		// store.commit("login/setvuex")
		// uni.onPushMessage((res) => {
		// 	// 后台提醒内容 需要后端配置,也可以不要
		//if (uni.getStorageSync("uuid") != data.senderId) {
			//let name = data.names ? data.names : "新消息"
			//let text = data.payload.text ? data.payload.text : "你有一条新消息待查看"
			// console.log(name);
			// console.log(text);
			//uni.createPushMessage({
			//	title: name,
			//	content: text,
			//	sound: "system",
			//	icon: "/static/images/logobc.png",
			//	 payload:{
			//	这里地方你可以随意组合你想要的数据,uni.onPushMessage会监听到你组合的数据。
			//	 },
		//		success: (res => {
		//			 console.log('成功创建')
		//		}),
		//	})
		//}
		// console.log("收到推送消息:", JSON.parse(res.data)) //监听推送消息
		// })

	});
}
// 重新连接
const reconnect = () => {
	console.log("开始断线重连!!!!!!!!!!!");
	// 确保已经关闭后再重新打开
	uni.closeSocket()
	socketTask = '';
	console.log("重新连接中...");
	// console.log(url + token);
	sokcet(url + token)
}
//向后端发送信息
const sendMsg = (msg) => {
	msg = JSON.stringify(msg)
	// console.log(msg);
	//通过 WebSocket 连接发送数据
	uni.sendSocketMessage({
		data: msg,
		success() {
			// console.log("成功");
		},
		fail() {
			console.log("失败");
			uni.showLoading({
				title: "加载中..."
			})
			setTimeout(() => {
				uni.hideLoading()
			}, 1000)
			if (!meClose) {
				reconnect()
			}
		},
	});
}
// 手动关闭连接
const stop = () => {
	// 主动关闭连接
	meClose = true
	uni.closeSocket({
		success() {
			console.log("手动关闭成功!");
			clearInterval(Time) //关闭定时器
			clearInterval(XTime) //关闭心跳定时器
			// 确保已经关闭
			socketTask = null;
		}
	})
}
// 导出方法
export const websocetObj = {
	sokcet, //连接
	stop, //关闭
	sendMsg //发送
};

我是用uniapp 的api封装的 在外面也可以直接用uniapp的api操作

只有在开始调用连接需要用封装的方法调用

在需要使用封装的方法的页面 引入js

    import {
        websocetObj
    } from "@/API/websocket.js"

 完善重连

在app.vue的onShow生命周期发送心跳检测是否连接(写在这个生命周期可以提高连接速度)

// 发送一次心跳,没有成功就触发重新连接
  websocetObj.sendMsg("2000")

调用连接方法

//请求连接
 websocetObj.sokcet()

关闭连接

 // 关闭连接
  websocetObj.stop()

 发送消息

sendTextMessage() { //发送消息
                if (this.content.trim() != '') {
                    let date = new Date()
                    let jsondata = {
                        groups: 0,
                        payload: {
                            text: this.content,
                            tpUrl: "",
                            spUrl: ""
                        },
                        receiverId: this.frienduuid,
                        senderId: this.user.uuid,
                        names: this.user.names,
                        avatar: this.user.avatar,
                        status: "success",
                        timestamp: date.getTime(),
                        type: "text"
                    };

                     // 使用封装方法发送
                    // websocetObj.sendMsg(jsondata)

                    // 使用uniapp 原生方法发送(我使用原生方法是因为想加一个消息发送失败提醒)
                    let msg = JSON.stringify(jsondata);
                    uni.sendSocketMessage({
                        data: msg,
                        success: () => {
                            //发送成功的方法
                            console.log("给" + this.title + "消息发送成功");
                        },
                        fail() {
                            uni.showToast({
                                title: '消息发送失败,请检查网络',
                                icon: 'none'
                            });
                        }
                    });
                    // 调用滚动到最下面的方法
                    this.scrollToBottom();
                    // 清空输入框
                    this.content = "";
                }
            },

 这个就是断线重连的过程 自动检测到服务器断线然后自动重新连接,中间报错是正常的没有连接到的报错,直到连接成功获取离线消息表示连接好了

 封装思想:

通过uniapp提供的API方法进行封装

断线重连机制:

通过发送心跳检测是否能够发送成功判断是否连接

 有不理解的地方欢迎私信或者评论问!!

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

巨蟹座守护骑士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值