1、WebSocket 是一种网络协议,用于在客户端和服务器之间进行双向通信。它允许在一个单独的 TCP 连接上进行全双工通信,因此比传统的 HTTP 请求-响应模型更高效。

1.1、WebSocket 协议通过在 HTTP 握手期间建立握手协议升级机制来启动连接。一旦建立连接,客户端和服务器可以在任何时候向对方发送数据。与传统的 HTTP 连接不同,WebSocket 连接保持打开状态,直到其中一方关闭连接或网络错误导致连接中断。

1.2、WebSocket 可以用于实时 Web 应用程序、多人在线游戏、聊天应用程序等场景,可以提供更低的延迟和更快的响应速度。WebSocket 协议也得到了广泛支持,现代浏览器和服务器都已经内置了 WebSocket 支持,许多编程语言和框架也提供了 WebSocket 实现。

2、先判断浏览器是否支持:if(window.WebSocket)

if(window.WebSocket){

console.log("支持")

}else{

console.log("不支持")

}

3、WebSocket是一种通信协议,用于在客户端和服务器之间进行双向通信。它允许Web浏览器和服务器之间实时交换数据,可以替代传统的HTTP轮询技术。

3.1、以下是WebSocket的基本使用步骤:

客户端通过JavaScript代码创建WebSocket对象,指定WebSocket服务器的地址:

var socket = new WebSocket("ws://example.com/socket");

当连接成功建立后,WebSocket对象的onopen回调函数会被调用。在这个回调函数中,您可以执行一些初始化操作或发送第一条消息:

socket.onopen = function(event) {

  // 在此处执行初始化操作或发送第一条消息

};

当WebSocket接收到来自服务器的数据时,WebSocket对象的onmessage回调函数会被调用,并将接收到的数据作为参数传递给该函数:

socket.onmessage = function(event) {

  console.log("收到消息:" + event.data);

};

客户端可以通过WebSocket对象的send()方法向服务器发送消息:

socket.send("Hello, server!");

当客户端不再需要WebSocket连接时,应该调用WebSocket对象的close()方法关闭连接:

socket.close();

服务器也可以通过WebSocket对象发送消息到客户端。当服务器发送消息时,客户端的onmessage回调函数会被调用,客户端可以在该回调函数中处理接收到的消息。

以上是WebSocket最基本的使用方法。除此之外,WebSocket还支持多种高级特性,例如二进制数据传输、ping/pong帧、断开重连等。

3.2、前后端链接的基础使用:

WebSocket 是一种在 Web 应用程序中实现双向通信的协议。在 Node.js 中,可以使用 ws 模块来创建 WebSocket 服务器。

下面是一个简单的示例:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8281 });

wss.on('connection', (ws) => {

 console.log('Client connected');

 ws.on('message', (message) => {

   console.log(`前端数据: ${message}`);

   ws.send(`发送给前端: ${message}`);

});

 ws.on('close', () => {

   console.log('断开链接');

});

});

这个例子创建了一个 WebSocket 服务器,监听端口 8080。当客户端连接时,会触发 connection 事件,并打印出 "Client connected"。然后,当收到客户端发送的消息时,会触发 message 事件,并打印出接收到的消息,同时将消息原样返回给客户端。最后,当客户端断开连接时,会触发 close 事件,并打印出 "Client disconnected"。

在客户端,可以使用浏览器内置的 WebSocket API 或者第三方库(如 Socket.IO)来与服务器建立连接并进行通信。例如:

const socket = new WebSocket('ws://localhost:8281');

socket.addEventListener('open', () => {

 console.log('建立链接');

});

socket.addEventListener('message', (event) => {

 console.log(`后端发送的数据: ${event.data}`);

});

socket.addEventListener('close', () => {

 console.log('关闭链接');

});

socket.send('发送数据给后端');

这个例子创建了一个 WebSocket 连接,连接到本地的 WebSocket 服务器。当连接建立时,会触发 open 事件,并打印出 "Connected to server"。然后,当收到服务器发送的消息时,会触发 message 事件,并打印出接收到的消息。最后,当连接断开时,会触发 close 事件,并打印出 "Disconnected from server"。在连接建立后,客户端可以使用 send 方法向服务器发送消息。

4、WebSocket的前端配置:

if (window.WebSocket) {

const ws = new WebSocket('ws://localhost:8888')

console.log(ws)

ws.onopen = () => {

 console.log('前端已经连接后端成功!')

}

ws.onerror = () => {

 console.log('前端和后端连接错误!')

}

ws.onclose = () => {

 console.log('后端关闭连接!')

}

ws.onmessage = data => {

 console.log('后端给前端推送信息了..,', data)

}

} else {

alert('您的浏览器不支持WebSocket,请升级您的浏览器')

}

5、WebSocket的后端配置:

5.1、下载模块:cnpm i ws --save

5.2、基本操作:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8888});

wss.on('connection', (ws) => {

 console.log('Client connected');

 ws.on('message', (message) => {

   console.log(`前端数据: ${message}`);

   ws.send(`发送给前端: ${message}`);

});

 ws.on('close', () => {

   console.log('断开链接');

});

});

6、 wss.clients.forEach():多人链接同一个端口,将每个人发送的消息都发送前端,实现多人聊天

6.1、"wss.clients.forEach()"将会对WebSocket服务器的每个客户端执行指定的操作。例如,可以使用它来向所有连接的客户端广播消息。

// 引入模块 npm i ws --save 1.nodejs-websocket

const WebSocket = require('ws');

// 创建一个WebSocketServer的实例,监听端口8080

const wss = new WebSocket.Server({ port: 8888 });

// 监听连接

wss.on('connection', (ws) => {

// console.log(wss.clients);

// ws.on('message', function incoming(message) {

// console.log('received: %s', message);

// ws.send('Hi Client');

 // });//当收到消息时,在控制台打印出来,并回复一条信息

ws.on('message', (mes) => {

 console.log(JSON.parse(mes));

//多人链接同一个端口,将每个人发送的消息都发送前端,实现多人聊天

 wss.clients.forEach((client) => {

  client.send(JSON.parse(mes));

});

})

// ws.send('Hello Client!')

});

7、二次封装WebSocket:

7.1、后端:在utils工具包创建WebSocket_server.js文件:

// 导入fs模块

const fs = require('fs');

// 导入path模块

const path = require('path');

// 引入模块 npm i ws --save 1.nodejs-websocket 2.websocket.io

const WebSocket = require('ws');

// 创建一个WebSocketServer的实例,监听端口8080

const wss = new WebSocket.Server({ port: 8888 });

// 封装listen暴露出去

const listen = () => {

// 监听连接

wss.on('connection', (ws) => {

 console.log('cake-admin连接进来啦...');

 // ws.on('message', function incoming(message) {

 // console.log('received: %s', message);

 // ws.send('Hi Client');

 // });//当收到消息时,在控制台打印出来,并回复一条信息

 ws.on('message', (mes) => {

  console.log(JSON.parse(mes));

  // 多人发送响应,比如多人聊天室

  // wss.clients.forEach((client) => {

  // client.send(JSON.parse(mes));

  // });

  // 单人发送响应,比如管理后台

  // ws.send('Hello Client!')

  let result = JSON.parse(mes);

  // console.log(typeof result);

  if (result.echarts === 'option1') {

   fs.readFile(path.resolve(__dirname, '../data/option1.json'), 'utf-8', (err, data) => {

    if (err) throw err;

    // 2.第二种方式: 在获取数据的时候,通过toString()转换成字符串

    // console.log(data.toString());

    // console.log(data); // {'one':[],'two':[],'three':[],'four':[]}

    data = JSON.parse(data);

    // 封装随机数函数

    function rand(max, min) {

     return Math.floor(Math.random() * (max - min + 1) + min)

    }

    // 向数据库实时查询数据是否有更新

    setInterval(() => {

     for (let i = 0; i < 12; i++) {

      data.one[i] = rand(20, 1)

      data.two[i] = rand(20, 1)

      data.three[i] = rand(20, 1)

      data.four[i] = rand(20, 1)

    }

     // console.log(data);

     // res.send(data);

     ws.send(JSON.stringify(data))

    }, 2000)

  })

  }

})

 // ws.send('Hello Client!')

});

}

module.exports = listen;

7.2、前端:在utils工具包创建WebSocket.js文件:函数式封装:

var websock = null;

let rec; //断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码

let isConnect = false; //连接标识 避免重复连接

let checkMsg = "heartbeat"; //心跳发送/返回的信息 服务器和客户端收到的信息内容如果如下 就识别为心跳信息 不要做业务处理

// 注册全局的回调函数

let globalCallback = function () { };

let createWebSocket = () => {

try {

 // websocket 初始化

 initWebSocket(); //初始化websocket连接

} catch (e) {

 console.log("尝试创建连接失败");

 // websocket 重新连接

 reConnect(); //如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接

}

};

//定义重连函数

let reConnect = () => {

console.log("尝试重新连接");

if (isConnect) return; //如果已经连上就不在重连了

rec && clearTimeout(rec);

rec = setTimeout(function () { // 延迟5秒重连 避免过多次过频繁请求重连

 createWebSocket();

}, 5000);

};

//设置关闭连接

let closeWebSocket = () => {

websock.close();

};

//心跳设置

var heartCheck = {

timeout: 20000, //每段时间发送一次心跳包 这里设置为20s

timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)

start: function () {

 this.timeoutObj = setTimeout(function () {

  if (isConnect) websock.send(checkMsg);

}, this.timeout);

},

reset: function () {

 clearTimeout(this.timeoutObj);

 this.start();

}

};

// 初始化websocket

function initWebSocket() {

// ws地址 -->这里是你的请求路径

var ws = "ws://localhost:8888"

// 创建websocket连接

websock = new WebSocket(ws)

// 监听后端的响应

websock.onmessage = function (e) {

 websocketonmessage(e)

}

// 监听websocket的关闭

websock.onclose = function (e) {

 websocketclose(e)

}

// 监听websocket的连接

websock.onopen = function () {

 websocketOpen()

 // heartCheck.start();

}

// 连接发生错误的回调方法

websock.onerror = function () {

 console.log('WebSocket连接发生错误')

 isConnect = false; //连接断开修改标识

 reConnect(); //连接错误 需要重连

}

}

// 实际调用的方法

function sendSock(agentData, callback) {

globalCallback = callback

// console.log(globalCallback)

if (websock.readyState === websock.OPEN) {

 // 若是ws开启状态

 websocketsend(agentData)

} else if (websock.readyState === websock.CONNECTING) {

 // 若是 正在开启状态,则等待1s后重新调用

 setTimeout(function () {

  sendSock(agentData, callback)

}, 1000)

} else {

 // 若未开启 ,则等待1s后重新调用

 setTimeout(function () {

  sendSock(agentData, callback)

}, 1000)

}

}

function getSock(callback) {

globalCallback = callback

}

// 数据接收

function websocketonmessage(e) {

// console.log(e.data)

let O_o = JSON.parse(decodeUnicode(e.data))

console.log(O_o);

if (!O_o) {

 heartCheck.reset();

} else {

 if (O_o.msg == "open success") {

  sessionStorage.setItem("wid", O_o.wid);

} else {

  // console.log(O_o);

  globalCallback(O_o);

}

}

// globalCallback(JSON.parse(e.data))

function decodeUnicode(str) {

 str = str.replace(/\\/g, "%");

 //转换中文

 str = unescape(str);

 //将其他受影响的转换回原来

 str = str.replace(/%/g, "\\");

 //对网址的链接进行处理

 str = str.replace(/\\/g, "");

 return str;

}

}

// 数据发送

function websocketsend(agentData) {

console.log(JSON.stringify(agentData))

websock.send(JSON.stringify(agentData))

}

// 关闭

function websocketclose(e) {

console.log(e)

isConnect = false; //断开后修改标识

console.log('connection closed (' + e.code + ')')

}

// 创建 websocket 连接

function websocketOpen(e) {

console.log('连接成功')

}

// initWebSocket()

// 将方法暴露出去

export {

initWebSocket,

sendSock,

getSock,

createWebSocket,

closeWebSocket

};

7.2、前端:在utils工具包创建WebSocket.js文件:类式封装:

// 单例模式的类封装

export default class SocketService {

static instance = null;

static get Instance() {

 if (!this.instance) {

  this.instance = new SocketService();

}

 return this.instance;

}

// 和服务端连接的socket对象

ws = null;

// 存储回调函数

callBackMapping = {};

// 标识是否连接成功

connected = false;

// 记录重试的次数

sendRetryCount = 0;

// 重新连接尝试的次数

connectRetryCount = 0;

// 定义连接服务器的方法

connect() {

 // 连接服务器

 if (!window.WebSocket) {

  return console.log('您的浏览器不支持WebSocket');

}

 let url = 'ws://localhost:8888';

 this.ws = new WebSocket(url);

 // 连接成功的事件

 this.ws.onopen = () => {

  console.log('连接服务端成功了');

  this.connected = true;

  // 重置重新连接的次数

  this.connectRetryCount = 0;

};

 // 1.连接服务端失败

 // 2.当连接成功之后, 服务器关闭的情况

 this.ws.onclose = () => {

  console.log('连接服务端失败');

  this.connected = false;

  this.connectRetryCount++;

  setTimeout(() => {

   this.connect();

  }, 500 * this.connectRetryCount);

};

 // 得到服务端发送过来的数据

 this.ws.onmessage = msg => {

  console.log(msg.data, '从服务端获取到了数据');

};

}

// 回调函数的注册

registerCallBack(socketType, callBack) {

 this.callBackMapping[socketType] = callBack;

}

// 取消某一个回调函数

unRegisterCallBack(socketType) {

 this.callBackMapping[socketType] = null;

}

// 发送数据的方法

send(data) {

 // 判断此时此刻有没有连接成功

 if (this.connected) {

  this.sendRetryCount = 0;

  try {

   this.ws.send(JSON.stringify(data));

  } catch (e) {

   this.ws.send(data);

  }

} else {

  this.sendRetryCount++;

  setTimeout(() => {

   this.send(data);

  }, this.sendRetryCount * 500);

}

}

}

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: