新建一个文件 websocket.js
// 定义websocket 地址
let socketurlDev = "ws://192.000.0.0:8085/websocket/admin/"; //开发环境
let socketurlProd = "wss://123456789.cn/prod-api/websocket/admin/"; //正式环境
// 重连锁, 防止过多重连
let reconnectLock = false;
// 定义一个消息发送中(包含发送失败的)的字典
window.messageSendingDic = {};
// 定义一个消息websocket连接状态的字段, 并且要绑定到widow上, 方便调用
// 0 未连接, 1 连接成功 2 连接中
window.webSocketState = 0;
// 定义连接服务器方法
function connectWebsocket(tenantInfo){
console.log("tenantInfo",tenantInfo)
//如果用户已登录, 进行连接websoket, 如果没有登陆, 登录后进行连接 用token判断
// 创建一个websocket连接
// let webSocket = new WebSocket(socketurl);
// 如果想要传token, 因为ws不支持通过设置header, 所以直接在地址中加参数,
let socketurl= ''
if (process.env.NODE_ENV === 'production') { // 生产环境下的配置
socketurl = `${socketurlProd}${tenantInfo.tenantId}`
} else if (process.env.NODE_ENV === 'development') {// 开发环境下的配置
socketurl = `${socketurlDev}${tenantInfo.tenantId}`
} else if (process.env.NODE_ENV === 'test') {// 测试环境下的配置
socketurl = `${socketurlDev}${tenantInfo.tenantId}`
}
let webSocket = new WebSocket(socketurl);
// 监听webSocket的各个状态
// 连接成功
webSocket.onopen = function() {
console.log("websocket连接成功")
// 连接成功后将连接状态改变
window.webSocketState = 1;
// 连接成功后, 要将消息队列里面的消息重新发送出去(底层重发, 和页面无关)
for(let session in window.messageSendingDic){
session.forEach(message => {
// 重发消息
reSendMessage(message)
});
}
}
// 连接出错
webSocket.onerror = function(error){
console.log("websocket连接出错", error);
// 进行重连
reconnectWebsocket();
}
// 连接关闭
webSocket.onclose = function(result){
console.log("websocket连接关闭", result);
if(result == "退出登录"){
return
}
// 进行重连
reconnectWebsocket();
}
// 接受到消息
webSocket.onmessage = function(message){
console.log("websocket接受到消息", message);
// 将受到的消息进行分类, 分发处理
formatAcceptMessage(message)
}
// 将webSocket绑定到window上面, 方便后续调用
window.webSocket = webSocket;
}
// 定义重连方法 如果连接失败, 或者关闭,
function reconnectWebsocket(){
// 如果正在重连, 则返回
if(reconnectLock){
return;
}
// 进行加锁
reconnectLock = true;
// 重连时将连接状态改变
window.webSocketState = 2;
// 为了防止过多请求, 1s后进行重连
setTimeout(function(){
// 解锁
reconnectLock = false;
// 进行连接, 如果失败接着重连
// connectWebsocket();
}, 1000)
}
/**
* 关闭websocket 退出时会用到
*
*/
function closeWebsocket(){
window.webSocket.onclose("退出登录")
}
// 定义发送消息的方法 message 格式为json
/**
*
* @param {
* message: "内容",
* id: "xxxxxxx"
* } message 消息内容
* @param "1" messageType 消息类型
* @param "QueryMsg" messageClass 附加字段吗消息类, 这里是以protobufjs的消息类为例
*/
function sendMessage(message, messageType, messageClass) {
// 这里可以对message做一些格式化处理
let formaterMessge = message;
// 将消息添加到发送中的数组中进行记录
// 先判断该回话有没有对应的数组, 如果没有就创建, 在添加, 如果有直接添加
if(window.messageSendingDic[message.sessionId]) {
window.messageSendingDic[message.sessionId].push(formaterMessge);
} else {
window.messageSendingDic[message.sessionId] = [];
window.messageSendingDic[message.sessionId].push(formaterMessge);
}
// 如果websocket连接成功, 进行发送消息
if(window.webSocketState == 1) {
formaterMessge = JSON.stringify(formaterMessge)
// 这里就可以直接用window调用了
window.webSocket.send(formaterMessge);
} else {
// 如果websocket没有连接成功, 直接告诉消息发送页面消息发送失败, 模拟接受到消息, 发给对应页面
let formaterMessge = {};
// 将处理后的消息进行发送通知, 通知给需要的页面进行处理, 在需要的页面进行监听
// 注意: 使用页面添加window.addEventListener("acceptNewMessage", this.testAction)
window.dispatchEvent(new CustomEvent("acceptNewMessage", formaterMessge));
}
}
// 定义重发送消息的方法 message 格式为json
/**
*
* @param {
* message: "内容",
* id: "xxxxxxx"
* } message 消息内容
* @param "1" messageType 消息类型
* @param "QueryMsg" messageClass 附加字段吗消息类, 这里是以protobufjs的消息类为例
*/
function reSendMessage(message) {
// 如果websocket连接成功, 进行发送消息
if(window.webSocketState == 1) {
// 这里就可以直接用window调用了
window.webSocket.send(message);
}
}
// 定义收到消息进行消息解析的方法
function formatAcceptMessage(message) {
// 处理消息. 格式化
let formaterMessge = message;
// 将发送成功的消息从发送中移除
if(window.messageSendingDic[message.sessionId]) {
let sendingArray = window.messageSendingDic[message.sessionId];
// 过滤发送成功的
window.messageSendingDic[message.sessionId] = sendingArray.filter(msg => {
return msg.id != message.id
});
}
// 将处理后的消息进行发送通知, 通知给需要的页面进行处理, 在需要的页面进行监听
// 注意: 使用页面添加window.addEventListener("acceptNewMessage", this.testAction)
// CustomEvent 必须使用detail为参数
window.dispatchEvent(new CustomEvent("acceptNewMessage",{
detail:formaterMessge
}
));
}
// 如果服务器端有消息确认, 可以根据消息确认, 添加消息是否发送成功的状态,
// 需要单独创建一个数组, 用来存放发送中的数据(包含发送失败的数据)
module.exports = {
connectWebsocket,
sendMessage
}
使用
import {connectWebsocket,sendMessage} from "@/utils/websocket.js"
//开始连接
connectWebsocket({tenantId:123})
//发送消息
sendMessage("需要发送的内容")
// 这里监听收到的消息
window.addEventListener("acceptNewMessage", (event)=>{
this.message = event.detail.data
console.log("acceptNewMessage",event.detail.data)
})