React 函数式组件使用Websocket
其实功能是比较简单,只要理解到hooks怎么在函数式组件工作的,就能写出来。同时,我觉得这几篇文章讲解hook非常好。
用动画和实战打开 React Hooks(一):useState 和 useEffect
下面直接上代码:
import SockJS from 'sockjs-client';
import { Subject } from 'rxjs';
export default class {
get = new Subject();
SocketApp: any = undefined;
// 链接状态
LinkConnected: boolean = false;
// 重连超时计时器
ReconnectTimer: any = null;
HeartBeat: any = null;
// 心跳计时器
HeartBeatTimer: any = null;
// 服务超时计时器
$ServerTimer: any = null;
reconnect() {
if (this.LinkConnected) {
return;
}
this.LinkConnected = true;
this.ReconnectTimer = setTimeout(() => {
console.info('websocket 尝试重连...');
this.LinkConnected = false;
this.createConnect();
}, 5000);
}
/**
*
* @param url
* 创建websocket对象
*/
createConnect(url?: string) {
if (!url) {
url = `http://${window.location.host}/rest/websocket`;
}
this.SocketApp = new SockJS(url);
this.SocketApp.onclose = () => {
console.log('websocket 链接关闭');
this.reconnect();
};
this.SocketApp.onopen = () => {
console.info('websocket is open');
// 心跳检查
this.HeartBeatCheck();
};
this.SocketApp.onmessage = (data: any) => {
const DATA = JSON.parse(data.data);
if (DATA.type === 'wbs') {
this.get.next(DATA);
}
// 心跳检查
this.HeartBeatCheck();
};
}
/**
* 心跳检查
*/
HeartBeatCheck() {
if (this.HeartBeatTimer) {
clearTimeout(this.HeartBeatTimer);
}
if (this.$ServerTimer) {
clearTimeout(this.$ServerTimer);
}
this.HeartBeatTimer = setTimeout(() => {
this.SocketApp.send('{"type":"heart"}');
// 发送消息后10秒,没有响应,即代表websocket失去响应,10s后进入关闭程序
this.$ServerTimer = setTimeout(() => {
this.SocketApp.close();
}, 10000);
}, 10000);
}
Close() {
if (this.SocketApp) {
this.SocketApp.close();
this.LinkConnected = true;
}
}
}
import WebsocketService from '@/services/websocket-service';
const $Websocket: any = useRef();
const [SocketMsg, SetSocketMsg] = useState({});
useEffect(() => {
$Websocket.current = new WebsocketService();
$Websocket.current.createConnect();
return () => {
$Websocket.current.Close();
};
}, []);
useEffect(() => {
$Websocket.current.get.subscribe((msg: any) => {
console.log(msg);
});
}, [SocketMsg]);
其中还可以使用消费全局的state的方式,待下次更新。