node服务
- server.js
- 首先要npm i websocket
/* server.js 服务器 */
export function ws() {
// 引入
const WebSocketServer = require("websocket").server;
const http = require("http");
const port = 8000;
let time = 0;
// 创建服务器
const server = http.createServer((request, response) => {
console.log(
`${new Date().toLocaleDateString()} Received request for ${request.url}`
);
response.writeHead(404);
response.end();
});
server.listen(port, () => {
console.log(
`${new Date().toLocaleDateString()} Server is listening on port ${port}`
);
});
// websocket 服务器
const wsServer = new WebSocketServer({
httpServer: server,
});
// 建立连接
wsServer.on("request", (request) => {
// 当前的连接
console.log(request.origin, "=======request.origin=======");
const connection = request.accept(null, request.origin);
console.log(`${new Date().toLocaleDateString()} 已经建立连接`);
setInterval(() => {
const obj = {
title: "标题" + time++,
value: "内容" + time++,
};
connection.send(JSON.stringify(obj));
}, 2000);
// 监听客户端发来的的消息
connection.on("message", (message) => {
console.log("message========>", message);
if (message.type === "utf8") {
console.log("Received Message: " + message.utf8Data);
// connection.sendUTF(message.utf8Data);
} else if (message.type === "binary") {
// binary 二进制
console.log(
"Received Binary Message of " + message.binaryData.length + " bytes"
);
// connection.sendBytes(message.binaryData);
}
});
// 监听当前连接 当断开链接(网页关闭) 触发
connection.on("close", (reasonCdoe, description) => {
console.log(
`${new Date().toLocaleDateString()} ${
connection.remoteAddress
} 断开链接`
);
});
});
}
- vue3 封装websocket
websocket.ts
let websock = null as any;
let messageCallback = null as any;
let resCallback = null as any;
let errorCallback = null as any;
let wsUrl = "";
let tryTime = 0;
let interval = null as any;
let data = null as any;
let state = false;
// 接收ws后端返回的数据
function websocketonmessage(e:any) {
if (e.data instanceof Blob && e.data.size === 0) {
//心跳
messageCallback(e.data);
} else {
//返回数据
messageCallback(JSON.parse(e.data));
}
}
/**
* 发起websocket连接
* @param {Object} agentData 需要向后台传递的参数数据
*/
function websocketSend(agentData: any) {
// 加延迟是为了尽量让ws连接状态变为OPEN
setTimeout(() => {
// 添加状态判断,当为OPEN时,发送消息
if (websock.readyState === websock.OPEN) {
// websock.OPEN = 1
// 发给后端的数据需要字符串化
if (agentData == "ping") {
//发送心跳
const pingMsg = new Uint8Array();
websock.send(pingMsg);
} else {
//发送消息
websock.send(JSON.stringify(agentData));
}
}
if (websock.readyState === websock.CLOSED) {
// websock.CLOSED = 3
console.log("websock.readyState=3", "ws连接断开");
clearInterval(interval);
errorCallback();
}
}, 500);
}
//向后端发送消息
export function websocketSendMess(agentData :any) {
// websock.send(JSON.stringify(agentData));
}
// 关闭ws连接
function websocketclose(e: any) {
// e.code === 1000 表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
// e.code !== 1000 表示非正常关闭。
//可以根据code情况判断 是否要重连
if (e) {
console.log("ws连接异常,请稍候重试");
clearInterval(interval);
errorCallback();
// 如果需要设置异常重连则可替换为下面的代码,自行进行测试
//重新连接几次后 是否继续重新 自行判断tryTime
setTimeout(function () {
websock = null;
tryTime++;
sendWebsocket(wsUrl, messageCallback, resCallback, errorCallback);
console.log(`第${tryTime}次重连`);
}, 3 * 1000);
}
}
// 建立ws连接
function websocketOpen(e?: any) {
tryTime = 0;
resCallback(e);
}
// 初始化weosocket
function initWebSocket() {
if (typeof WebSocket === "undefined") {
console.log("您的浏览器不支持WebSocket,无法获取数据");
return false;
}
// ws请求完整地址
websock = new WebSocket(wsUrl);
websock.onmessage = function (e: any) {
websocketonmessage(e);
};
websock.onopen = function () {
websocketOpen();
};
websock.onerror = function () {
console.log("ws连接异常,请稍候重试");
closeWebsocket();
errorCallback();
};
websock.onclose = function (e: any) {
websocketclose(e);
};
}
/**
* 发起websocket请求函数
* @param {string} url ws连接地址
* @param {function} successCallback 接收到ws数据,对数据进行处理的回调函数
* @param {function} errCallback ws连接错误的回调函数
* @param {function} resorCallback ws连接成功的回调函数
*/
export function sendWebsocket(
url: string,
successCallback: any,
errCallback: any,
resorCallback: any
) {
wsUrl = url;
initWebSocket();
messageCallback = successCallback;
resCallback = resorCallback;
errorCallback = errCallback;
// websocketSend(agentData);
//保持心跳
clearInterval(interval);
interval = setInterval(() => {
websocketSend("ping");
}, 1000 * 5);
}
/**
* 关闭websocket函数
*/
export function closeWebsocket() {
if (websock) {
clearInterval(interval);
websock.close(); // 关闭websocket
websock.onclose(); // 关闭websocket
}
}
页面组件调用
<template>
<div class="app"></div>
</template>
<script setup lang="ts">
import { sendWebsocket, closeWebsocket, websocketSendMess } from "@/websocket";
import { onBeforeUnmount, onMounted } from "vue";
onMounted(() => {
sendWebsocket(
"ws://localhost:8081",
wsMessage,
wsError,
succeed
);
}),
onBeforeUnmount(() => {
closeWebsocket()
})
// ws连接成功,后台返回的ws数据,组件要拿数据渲染页面等操作
function wsMessage(data: any) {
const dataJson = data;
console.log("接收信息", dataJson);
}
// ws连接失败,组件要执行的代码
function wsError() {
console.log("ws连接失败");
}
// ws连接成功,组件要执行的代码
function succeed(e: any) {
console.log("ws连接成功");
}
</script>
<style lang="scss"></style>