简易版websocket封装及本地启动socket服务

2022-12-15 18:11:19 浏览数 (2)

使用node启动本地socket服务

  • 创建项目目录
代码语言:javascript复制
mkdir server
  • 初始化 npm
代码语言:javascript复制
npm init -y
  • 安装依赖库
代码语言:javascript复制
npm i nodejs-websocket -S
  • 创建服务文件
代码语言:javascript复制
const ws = require('nodejs-websocket');
const server = ws.createServer(connect => {
	connect.on("text", data => {
		console.log("received: " data);
		connect.sendText(data);
	});
	connect.on("close", (code, reason) => {
		console.log("connection closed!");
	});
	connect.on('error', ()=>{
		console.log("connection error!");
	});
});
server.listen('13000', ()=>{
	console.log("websocket server start success!");
});
  • 启动服务
代码语言:javascript复制
node server.js
  • websocket 连接测试

封装简易版 websocket

代码语言:javascript复制
let webSocket = null;
let isConnect = false; // 连接状态
let globalCallbacks = null;// 定义外部接收数据的回调函数
let reConnectNum = 0; // 重连次数

let websocketUrl = 'ws://127.0.0.1:5000';

// 心跳设置
let heartCheck = {
    heartbeatData: {
        DevID: {
            value: 1
        },
        DevHeart: {
            value: '1'
        }
    },// 心跳包
    timeout: 60 * 1000, // 每段时间发送一次心跳包 这里设置为60s
    heartbeat: null, // 延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
    start: function () {
        this.heartbeat = setInterval(() => {
            if (isConnect) {
                webSocketSend(this.heartbeatData);
            } else {
                this.clear();
            }
        }, this.timeout);
    },
    reset: function () {
        clearInterval(this.heartbeat);
        this.start();
    },
    clear: function() {
        clearInterval(this.heartbeat);
    }
};

// 初始化websocket
function initWebSocket(callbacks) {
    // 此callback为在其他地方调用时定义的接收socket数据的函数
    if (callbacks) {
        if (typeof callbacks === 'object') {
            globalCallbacks = callbacks;
        } else {
            throw new Error('callbacks is not a object');
        }
    }
    if ('WebSocket' in window) {
        webSocket = new WebSocket(websocketUrl);// 创建socket对象
    } else {
        console.log('该浏览器不支持websocket!');
        return;
    }
    // 打开
    webSocket.onopen = function() {
        webSocketOpen();
    };
    // 接收
    webSocket.onmessage = function(e) {
        webSocketOnMessage(e);
    };
    // 关闭
    webSocket.onclose = function(e) {
        webSocketOnClose(e);
    };
    // 连接发生错误的回调方法
    webSocket.onerror = function(e) {
        webSocketOnError(e);
    };
}

// 连接socket建立时触发
function webSocketOpen() {
    console.log('WebSocket连接成功');
    // 首次握手
    // webSocketSend(heartCheck.heartbeatData);
    isConnect = true;
    globalCallbacks.openCallback && globalCallbacks.openCallback();
    // heartCheck.start();
    reConnectNum = 0;
}

// 客户端接收服务端数据时触发,e为接受的数据对象
function webSocketOnMessage(e) {
    console.log('websocket信息:');
    console.log(e.data);
    const data = JSON.parse(e.data); // 根据自己的需要对接收到的数据进行格式化
    globalCallbacks.getSocketResult(data); // 将data传给在外定义的接收数据的函数
}

// socket关闭时触发
function webSocketOnClose(e) {
    // heartCheck.clear();
    isConnect = false; // 断开后修改标识
    globalCallbacks.closeCallback && globalCallbacks.closeCallback();
    console.log(e);
    console.log('webSocket已经关闭 (code:'   e.code   ')');
    // 被动断开,重新连接
    if (e.code === 1006) {
        if (reConnectNum < 3) {
            initWebSocket();
              reConnectNum;
        } else {
            console.log('websocket连接不上,请刷新页面或联系开发人员!');
        }
    }
}

// 连接发生错误的回调方法
function webSocketOnError(e) {
    // heartCheck.clear();
    isConnect = false; // 断开后修改标识
    console.log('WebSocket连接发生错误:');
    console.log(e);
}

// 发送数据
function webSocketSend(data) {
    webSocket.send(JSON.stringify(data));// 在这里根据自己的需要转换数据格式
}

// 在其他需要socket地方主动关闭socket
function closeWebSocket(e) {
    webSocket.close();
    // heartCheck.clear();
    isConnect = false;
    reConnectNum = 0;
}
// 在其他需要socket地方接受数据
function getSock(callback) {
    globalCallbacks.getSocketResult = callback;
}

// 在其他需要socket地方调用的函数,用来发送数据及接受数据
function sendSock(agentData) {
    // 下面的判断主要是考虑到socket连接可能中断或者其他的因素,可以重新发送此条消息。
    switch (webSocket.readyState) {
        // CONNECTING:值为0,表示正在连接。
        case webSocket.CONNECTING:
            setTimeout(function() {
                sendSock(agentData);
            }, 1000);
            break;
        // OPEN:值为1,表示连接成功,可以通信了。
        case webSocket.OPEN:
            webSocketSend(agentData);
            break;
        // CLOSING:值为2,表示连接正在关闭。
        case webSocket.CLOSING:
            setTimeout(function() {
                sendSock(agentData);
            }, 1000);
            break;
        // CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
        case webSocket.CLOSED:
            // do something
            break;
        default:
            // this never happens
            break;
    }
}

export default {
    initWebSocket,
    closeWebSocket,
    sendSock,
    getSock
};

在 Vue 中使用

  • 入口函数挂载
代码语言:javascript复制
// main.js
import socketApi from '@/utils/socket';
Vue.prototype.$socketApi = socketApi;
  • 组件中使用
代码语言:javascript复制
createWebSocket() {
	const callbacks = {
		getSocketResult: this.getSocketResult,
		openCallback: this.openCallback,
		closeCallback: this.closeCallback
	};
	this.$socketApi.initWebSocket(callbacks);
},

// 创建连接
created() {
	this.createWebSocket()
}

// 关闭连接
beforeDestroy() {
	this.$socketApi.closeWebSocket();
}

// 发送消息
this.$socketApi.sendSock();

0 人点赞