随着互联网的快速发展,程序员需要处理的业务场景也越来越多了,ajax对于一些常链接实时刷新数据特殊的场景的处理就显的很无力,于是webSocket出现了。
这次的博客将以websocket的链接,发送,监听,关闭,重连,重发几个步骤来讲解一下websocket的使用。
我将会封装一个websocket的构造函数来讲。
1 构建获取基本信息
class LangWs {
constructor(url) {
this.ws = '';
this.url = url;
this.connect()
}
connect() { // ws链接
this.ws = new WebSocket(this.url)
}
wsStatus() { // ws状态
return this.ws.readyState
}
}
2 发送消息
class LangWs {
constructor(url) {
this.ws = '';
this.url = url;
this.connect()
}
connect() {
this.ws = new WebSocket(this.url);
}
send(args) { // 发送
this.ws.send(args)
}
wsStatus() {
return this.ws.readyState
}
}
3 接受
class LangWs {
constructor(url) {
this.ws = '';
this.handers = new Map(); // 处理回调函数
this.url = url;
this.connect()
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onmessage = (event) => {
// 解析发过来的数据,看情况解压
if (this.handers.has(event.data.cmd)) {
this.handers.get(event.data.cmd)()
}
};
}
send(args) {
this.ws.send(args)
}
addHandler(cmd, fn) {
this.handers.set(cmd,fn)
}
wsStatus() {
return this.ws.readyState
}
}
4 关闭
class LangWs {
constructor(url) {
this.ws = '';
this.forceClose=false; // 用于判断是否重连
this.handers = new Map();
this.url = url;
this.connect()
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onmessage = (event) => {
// 解析发过来的数据,看情况解压
if (this.handers.has(event.data.cmd)) {
this.handers.get(event.data.cmd)()
}
};
}
send(args) {
this.ws.send(args)
}
addHandler(cmd, fn) {
this.handers.set(cmd,fn)
}
close() {
if (this.ws) {
this.forceClose = true;
this.ws.close()
}
}
wsStatus() {
return this.ws.readyState
}
}
5 重连
class LangWs {
constructor(url) {
this.ws = '';
this.forceClose=false; // 用于判断是否重连
this.reconnectInterval=1000; // 用于重连
this.handers = new Map();
this.url = url;
this.connect()
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onmessage = (event) => {
// 解析发过来的数据,看情况解压
if (this.handers.has(event.data.cmd)) {
this.handers.get(event.data.cmd)()
}
};
this.ws.onclose = () => {
if (this.forceClose) return; // 手动关闭,则关闭
setTimeout(() => { // 重连
this.connect();
}, this.reconnectInterval);
}
}
send(args) {
this.ws.send(args)
}
addHandler(cmd, fn) {
this.handers.set(cmd,fn)
}
close() {
if (this.ws) {
this.forceClose = true;
this.ws.close()
}
}
wsStatus() {
return this.ws.readyState
}
}
6 重发以及其他一些判断(都有备注)
class LangWs {
constructor(url) {
this.ws = ''; // ws实例
this.wsStatus = ''; // ws状态
this.reconnectInterval = 1000; // 重发事件
this.forceClose = false; // 判断是否重发
this.handers = new Map(); // 处理发送事件集合
this.subChannels = new Map(); // 重发事件集合
this.url = url; // ws url
this.connect() // 连接函数
}
connect() {
this.ws = new WebSocket(this.url);
this.wsStatus = this.ws.readyState;
if (this.wsStatus > 1) {
if (this.forceClose) {
return;
}
}
this.ws.onopen = () => { // 处理open事件
if (this.subChannels && this.subChannels.size) { // 重发事件
this.subChannels.forEach((item) => {
const args = {
event: 'sub',
params: item
};
this.send(JSON.stringify(args));
});
}
};
this.ws.onmessage = (event) => { // 处理回调函数
// 解析发过来的数据,看情况解压
if (this.handers.has(event.data.cmd)) {
this.handers.get(event.data.cmd)()
}
};
this.ws.onclose = () => { // 判断是否重发
if (this.forceClose) return;
setTimeout(() => {
this.connect();
}, this.reconnectInterval);
}
}
send(args) { // 发送数据
if (this.wsStatus === WebSocket.OPEN) {
this.ws.send(args);
this.resetSub(args.cmd) //记录发过的消息
}
}
// 添加处理函数
addHandler(cmd, fn) {
this.handers.set(cmd,fn)
}
removeHandler(cmd) { // 删除处理函数
if (cmd) {
this.handers.delete(cmd); // 删除事件
if (this.subChannels.has(cmd)) {
this.subChannels.delete(cmd);
}
}
}
resetSub(data) { // 消息处理函数
if (typeof data !== 'string') {
return;
}
const reqData = JSON.parse(data);
if (reqData.event === 'sub') { // 处理添加事件
this.subChannels.set(cmd, reqData.params);
}
}
close() { // 主动关闭
if (this.ws) {
this.forceClose = true;
this.ws.close()
}
}
}
还有一些心跳检查,事件处理可以自行配置,这个配置已经适合绝大多数场景了
最后在加一个使用案例;根据自己的数据格式来,做一些适当的改进。
import {LangWs} from './ws' // 写入自己文件路径
const socket = new LangWs('ws://localhost8080:80');
const args = {
id: '12121',
cmd: 'qqqqqqq'
};
socket.send(args);
socket.addHandler(args.cmd, (data) => {
console.log(11) // 这里处理自己的业务
});
socket.removeHandler(args.cmd); //在自己需要的地方断开
socket.close(); //在自己需要的地方关闭连接