以下方法用其中一个
一、方法1
1.新建socket.js
class socket {
constructor(url) {
this.is_open_socket = false //避免重复连接
this.url = url //地址
this.data = null
//心跳检测
this.timeout = 120000 //多少秒执行检测
this.heartbeatInterval = null //检测服务器端是否还活着
this.reconnectTimeOut = null //重连之后多久再次重连
try {
return this.socketInit()
} catch (e) {
console.log('catch');
this.is_open_socket = false
this.reconnect();
}
}
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
socketInit() {
this.socketTask = uni.connectSocket({
url: this.url,
success: () => {
console.log("正准备建立websocket中...");
// 返回实例
return this.socketTask
},
});
this.socketTask.onOpen((res) => {
console.log("WebSocket连接正常!");
clearTimeout(this.reconnectTimeOut)
clearTimeout(this.heartbeatInterval)
this.is_open_socket = true;
this.start();
// 注:只有连接正常打开中 ,才能正常收到消息
this.socketTask.onMessage((res) => {
console.log(res.data)
});
})
// 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
// uni.onSocketError((res) => {
// console.log('WebSocket连接打开失败,请检查!');
// this.is_open_socket = false;
// this.reconnect();
// });
// 这里仅是事件监听【如果socket关闭了会执行】
this.socketTask.onClose(() => {
console.log("已经被关闭了")
this.is_open_socket = false;
this.reconnect();
})
}
close() {
this.socketTask.close({
success(){
console.log("已经被关闭了")
}
})
}
//发送消息
send(value) {
// 注:只有连接正常打开中 ,才能正常成功发送消息
this.socketTask.send({
data: value,
async success() {
console.log("消息发送成功");
},
});
}
//开启心跳检测
start() {
this.heartbeatInterval = setInterval(() => {
/*this.data = {
value: "传输内容",
method: "方法名称"
}
console.log(this.data)
this.send(JSON.stringify(this.data));*/
this.send("ping")
}, this.timeout)
}
//重新连接
reconnect() {
//停止发送心跳
clearInterval(this.heartbeatInterval)
//如果不是人为关闭的话,进行重连
if (!this.is_open_socket) {
this.reconnectTimeOut = setTimeout(() => {
this.socketInit();
}, 120000)
}
}
//外部获取消息
getMessage(callback) {
this.socketTask.onMessage((res) => {
return callback(res)
})
}
}
export default socket
在页面使用
局部引用
import socket from '@/utils/socket.js'
调用
data(){
return(){
socket:null
}
},
mounted() {
this.socket = new wsRequest(
'ws://xxxx/' + userId
);
this.watchSocket();
},
unMounted(){
this.socket.close()
},
beforeUnmount(){
this.socket.close()
},
methods:{
//接受消息
watchSocket() {
this.socket.getMessage(opt => {
console.warn("消息接收:", opt);
})
},
}
二、方法2
使用pinia
先参考pinia搭建,跳转
import {
defineStore
} from 'pinia'
export const useSocketStore = defineStore("socket", {
state: () => {
return {
is_open_socket: false, //避免重复连接
data:"",
socketTask:null,
//心跳检测
timeout:120000, //多少秒执行检测
heartbeatInterval: null, //检测服务器端是否还活着
reconnectTimeOut: null //重连之后多久再次重连
}
},
actions: {
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
socketInit(url) {
this.socketTask = uni.connectSocket({
url: url,
success: () => {
console.log("正准备建立websocket中...");
// 返回实例
return this.socketTask
},
});
this.socketTask.onOpen((res) => {
console.log("WebSocket连接正常!");
clearTimeout(this.reconnectTimeOut)
clearTimeout(this.heartbeatInterval)
this.is_open_socket = true;
this.start();
// 注:只有连接正常打开中 ,才能正常收到消息
this.socketTask.onMessage((res) => {
//console.log(res.data)
});
})
// 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接
// uni.onSocketError((res) => {
// console.log('WebSocket连接打开失败,请检查!');
// this.is_open_socket = false;
// this.reconnect();
// });
// 这里仅是事件监听【如果socket关闭了会执行】
this.socketTask.onClose(() => {
console.log("已经被关闭了")
this.is_open_socket = false;
this.reconnect();
})
},
close() {
this.socketTask.close({
success(){
console.log("已经被关闭了")
}
})
},
//发送消息
send(data) {
// 注:只有连接正常打开中 ,才能正常成功发送消息
this.socketTask.send({
data: data,
async success() {
console.log("消息发送成功");
},
});
},
//开启心跳检测
start() {
this.heartbeatInterval = setInterval(() => {
/*this.data = {
value: "传输内容",
method: "方法名称"
}
console.log(this.data)
this.send(JSON.stringify(this.data));*/
this.send("ping")
}, this.timeout)
},
//重新连接
reconnect() {
//停止发送心跳
clearInterval(this.heartbeatInterval)
//如果不是人为关闭的话,进行重连
if (!this.is_open_socket) {
this.reconnectTimeOut = setTimeout(() => {
this.socketInit();
}, 120000)
}
},
//外部获取消息
getMessage(callback) {
this.socketTask.onMessage((res) => {
return callback(res)
})
}
}
})
页面引用
import {
useSocketStore
} from "@/store"
const socketStore = useSocketStore()
方法
import {
ref,
onMounted,
onUnmounted
} from "vue";
const userId = ref("") //当前用户id
onMounted(() => {
watchSocket();
})
onUnmounted(() => {
socketStore.close()
})
onBeforeUnmount(() => {
socketStore.close()
})
//接受消息
function watchSocket() {
socketStore.connectSocketInit('ws://xxx/' + userId.value)
socketStore.getMessage(opt => {
console.log("消息接收:", opt);
})
}
方法3
vuex
import {
wsURL
} from "@/utils/config.js"
export default {
namespaced: true,
state: {
socketTask: null,
timeoutObj: null,
reconnectCount: 0, //websocket连接次数,最大是3次
isConnectedSocket: false,
websocketUrl: 'ws://你的服务ip:9998/接口/', //websocket地址
},
mutations: {
WEBSOCKET_INIT(state, userId) {
let token = uni.getStorageSync('token')
let url = wsURL +`${userId},${token}`
state.socketTask = uni.connectSocket({
url, // url是websocket连接ip
success() {
state.isConnectedSocket = true;
console.log('websocket连接成功')
}
})
state.socketTask.onOpen((res) => {
console.log('WebSocket连接正常打开中...!');
// 开启检测
state.timeoutObj = setTimeout(() => {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
console.log('ping');
state.socketTask.send({
data: "ping"
});
}, 5000)
// 注:只有连接正常打开中 ,才能正常收到消息
state.socketTask.onMessage(res => {
clearTimeout(state.timeoutObj);
console.log(res)
console.log('收到服务器内容')
});
})
state.socketTask.onError((res) => {
console.log('WebSocket连接打开失败,请检查!');
});
},
WEBSOCKET_SEND(state, data) {
console.log("ws发送")
state.socketTask.send({
data: data,
async success() {
console.log('消息发送成功')
},
fail: (res) => {
console.log(res)
}
})
},
CLOSE_SOCKET(state) {
if (!state.socketTask) return
state.socketTask.close({
success(res) {
console.log('关闭成功', res)
},
fail(err) {
console.log('关闭失败', err)
}
})
}
},
actions: {
WEBSOCKET_INIT({
commit
}, url) {
commit('WEBSOCKET_INIT', url)
},
WEBSOCKET_SEND({
commit
}, data) {
commit('WEBSOCKET_SEND', data)
},
CLOSE_SOCKET({
commit
}) {
commit('CLOSE_SOCKET')
}
}
}
调用方法