赞
踩
在使用uniapp开发一个IM即时通讯系统时,需要用到websocket协议,包括对话等等
uni中封装websokect.js
//是否已经连接上ws let isOpenSocket = false //心跳间隔,单位毫秒 let heartBeatDelay = 3000 let heartBeatInterval = null //心跳时发送的消息文本 let heartBeatText = "" //最大重连次数 let reconnectTimes = 10 let reconnectInterval = null //重连间隔,单位毫秒 let reconnectDelay = 3000 let wsUrl = "ws://82.157.123.54:9010/ajaxchattest" // 可以测试用 let socketTask = null //这个参数是防止重连失败之后onClose方法会重复执行reconnect方法,导致重连定时器出问题 //连接并打开之后可重连,且只执行重连方法一次 let canReconnect = false //封装的对象,最后以模块化向外暴露, //init方法 初始化socketTask对象 //completeClose方法 完全将socketTask关闭(不重连) //其他关于socketTask的方法与uniapp的socketTask api一致 let ws = { socketTask: null, init, send, completeClose } function init(agentData, messageCallback) { // 两个参数:发送不同的标识&处理接收消息 socketTask = uni.connectSocket({ url: wsUrl, complete: () => {} }) socketTask.onOpen((res) => { console.log("ws连接成功") clearInterval(heartBeatInterval) clearInterval(reconnectInterval) isOpenSocket = true canReconnect = true send(JSON.stringify(agentData)); //开启心跳机制 // heartBeat() }) socketTask.onMessage((res) => { //自定义处理onMessage方法 // console.log(res) onWsMessage(res, messageCallback)// }) socketTask.onClose(() => { if (isOpenSocket) { console.log("ws与服务器断开") } else { console.log("连接失败") } isOpenSocket = false if (canReconnect) { reconnect() canReconnect = false } }) ws.socketTask = socketTask } function heartBeat() { heartBeatInterval = setInterval(() => { console.log(heartBeatText) send(JSON.stringify(heartBeatText)); }, heartBeatDelay) } function onWsMessage(event, messageCallback) { // 处理接收消息 const jsonStr = event.data writeToScreen('onWsMessage接收到服务器的数据: ', jsonStr) messageCallback(jsonStr) } function send(value) { ws.socketTask.send({ data: value, async success() { console.log("消息标识发送成功",value) } }); } function reconnect() { //停止发送心跳 clearInterval(heartBeatInterval) //如果不是人为关闭的话,进行重连 if (!isOpenSocket) { let count = 0; reconnectInterval = setInterval(() => { console.log("正在尝试重连") init(); count++ //重连一定次数后就不再重连 if (count >= reconnectTimes) { clearInterval(reconnectInterval) console.log("网络异常或服务器错误") } }, reconnectDelay) } } function completeClose() { //先将心跳与重连的定时器清除 clearInterval(heartBeatInterval) clearInterval(reconnectInterval) canReconnect = false ws.socketTask.close() } module.exports = ws
使用时需要在main.js引入并绑定在Vue的prototype上,这样就可以做到全局变量了
main.js
import ws from '路径' //找好自己的路径
Vue.prototype.$ws = ws
当你在某个vue页面需要使用socketTask的话,需要调用this.$ws.init(‘发送标识’,‘处理方法’)
发送消息
常见问题:为什么不是在main.js就把socketTask对象初始化呢?
因为大部分情况下socketTask对象是需要在一定条件下才初始化的,比如在登录之后,才需要使用。而不是一打开APP就去连接后端的websocket服务器了。
当然,如果需要在main.js中把socketTask对象初始化,可以直接在main.js中调用init方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。