const MODE = import.meta.env.MODE;
const hostname = MODE === 'production' ? 'xxx' : 'xxx';
const socketUrl = 'wss://' + hostname + '/ws';
class MyWebSocket {
constructor(props) {
this.props = props;
this.connect();
this.status = '';
this.pingPong = 'ping';
this.pingInterval = '';
this.pongInterval = '';
}
// 连接websocket
connect() {
const that = this;
this.ws = new WebSocket(socketUrl)
this.ws.onopen = function () {
console.log('WebScoket 连接成功!');
that.status = 'open';
const params = {
action: 'auth',
token: window.localStorage.getItem('token') || ''
}
if (that.ws && that.ws.readyState === 1) {
that.ws.send(JSON.stringify(params));
}
that.ceartCheck();
that.getMessage();
}
}
// 保活测试
ceartCheck() {
this.pingInterval = setInterval(() => {
if (this.ws.readyState === 1) {
this.ws.send(JSON.stringify({ action: 'heartbeat' }));
}
}, 30000); // 30s 客户端发送一次心跳包
this.pongInterval = setInterval(() => {
if (this.pingPong === 'ping') {
this.closeHandle('pingPong没有改变为pong');
}
this.pingPong = 'ping';
}, 60000); // 60s检测一次服务端是否返回10203
}
// 重连
closeHandle(err) {
if (this.status !== 'close') {
console.log(`断开,重连websocket:`, err);
if (this.pingInterval !== undefined && this.pongInterval !== undefined) {
// 清除定时器
clearInterval(this.pingInterval);
clearInterval(this.pongInterval);
}
this.connect(); // 重连
} else {
console.log(`websocket手动关闭!`);
}
}
// 服务端信息推送
getMessage() {
this.ws.onmessage = e => {
const data = JSON.parse(e.data);
if (data.code === 10201) {
console.log('认证成功:' + data.code);
} else if (data.code === 10202) {
console.log('心跳包发送成功:' + data.code);
} else if (data.code === 10200) {
console.log("推送消息啦: " + e.data);
this.props.callback(data);
} else if (data.code === 10203) { // 后端定时返回,以便确定是否断开连接
this.pingPong = 'pong'
} else {
console.log("报错啦: " + data);
}
};
}
// 手动关闭连接
close() {
clearInterval(this.pingInterval);
clearInterval(this.pongInterval);
this.status = 'close';
this.ws.close();
console.log('WebSocket Close!!');
}
}
export default MyWebSocket;
import MyWebSocket from '@/utils/webSocket';
let ws: any = null;
useEffect(() => {
if (window.localStorage.getItem('token')) {
ws = new MyWebSocket({
callback: (res) => {
console.log('消息内容:', res);
if (res.data.msg_type === 'order_declaration_boss_confirm_timeout') {
notification.open({
message: 'xxx',
description: 'xxx',
duration: 0,
btn: <Button type="primary" size="small" onClick={() => {
notification.destroy();
navigate('/xxx')
}}>查看超时工单</Button>,
icon: <InfoCircleOutlined style={{ color: '#108ee9' }} />,
});
}
}
});
return () => {
ws?.close();
}
}
}, [window.localStorage.getItem('token')])