前言
之前遇到过需要即时通讯的场景,刚开始使用的是通过轮询的方式,定时器3秒向服务器请求一次数据,后面发现如果在手机端长时间打开使用此功能的页面,可能会发生手机发热,甚至卡顿的现象。最后改用webSocket,可以实现全双工通信,让服务器主动向客户端发送请求。
接下来先介绍一下即时通信的实现方法?
-
轮询(Polling):
- 工作原理:客户端定时向服务器发送请求,询问是否有新数据可用。如果服务器有新数据,返回数据;如果没有,服务器返回空响应。客户端收到响应后立即再次发送请求,形成周期性的轮询过程。
- 优点:实现简单,大部分浏览器和服务器都支持。
- 缺点:频繁的请求和响应会导致不必要的网络开销,降低性能和效率。
- 适用场景:适用于数据更新频率不高且实时性要求不高的场景。
-
长轮询(Long Polling):
- 工作原理:客户端发送请求给服务器,服务器不立即返回响应,而是将请求挂起,等待有新数据时再返回响应。一旦客户端收到响应,立即再次发送请求,形成新的挂起请求。
- 优点:相较于轮询,减少了不必要的网络请求,降低了网络开销。
- 缺点:服务器需要维护大量挂起的请求,占用资源较多,不适用于高并发场景。
- 适用场景:适用于数据更新不频繁,但要求实时性相对较高的场景。
-
WebSocket:
- 工作原理:WebSocket 是一种全双工通信协议,通过建立持久性的连接,客户端和服务器可以随时发送和接收消息。连接建立后,双方可以直接发送消息,不需要频繁的握手过程。
- 优点:实现实时通信,降低了不必要的网络开销,性能高,支持跨域通信。
- 缺点:需要服务器和客户端都支持 WebSocket 协议。
- 适用场景:适用于需要实时通信的场景,如实时聊天、在线游戏等。
-
Server-Sent Events(SSE):
- 工作原理:SSE 是一种单向通信协议,允许服务器向客户端发送数据,但客户端不能向服务器发送数据。客户端通过
EventSource
对象订阅服务器的事件流,一旦有新数据可用,服务器会自动发送数据给客户端。 - 优点:实现简单,不需要像 WebSocket 那样进行双向握手,适用于服务器向客户端推送数据。
- 缺点:只支持单向通信,不适用于客户端向服务器发送请求。
- 适用场景:适用于服务器主动向客户端推送实时数据的场景,如推送通知、实时监控等。
- 工作原理:SSE 是一种单向通信协议,允许服务器向客户端发送数据,但客户端不能向服务器发送数据。客户端通过
前端如何使用 WebSocket?
在前端中使用 WebSocket 非常简单,首先需要在浏览器中创建一个 WebSocket 对象,然后通过该对象与服务器建立连接。一旦连接建立成功,前端可以通过发送和接收消息来实现与服务器的实时通信。
1. 创建 WebSocket 对象
在 JavaScript 中,可以通过以下代码创建 WebSocket 对象:
const socket = new WebSocket('ws://example.com'); // 根据实际情况替换为服务器的 WebSocket 地址
在上述代码中,我们创建了一个 WebSocket 对象,传入服务器的 WebSocket 地址作为参数。WebSocket 地址的协议可以是 ws
(未加密)或 wss
(加密)。
2. 监听事件
一旦 WebSocket 连接建立成功,就可以通过监听事件来处理连接状态和消息的收发。
socket.onopen = () => {
console.log('WebSocket连接已建立');
};
socket.onmessage = event => {
const message = event.data;
console.log('收到消息:', message);
};
socket.onclose = () => {
console.log('WebSocket连接已关闭');
};
socket.onerror = error => {
console.error('WebSocket连接错误:', error);
};
在上述代码中,我们监听了 onopen
事件(连接建立)、onmessage
事件(收到消息)、onclose
事件(连接关闭)、onerror
事件(连接错误)。每当相应的事件触发时,我们通过回调函数来处理相应的逻辑。
3. 发送和接收消息
一旦 WebSocket 连接建立成功,就可以通过 send()
方法来发送消息,同时通过 onmessage
事件来接收消息。
// 发送消息
socket.send('Hello, WebSocket!');
// 接收消息在上面的监听代码中已经处理
以上代码演示了如何在前端中创建 WebSocket 连接、发送和接收消息。当服务器和客户端建立连接后,它们可以随时通过 send()
方法和 onmessage
事件来实现实时通信。
4.websocket的心跳机制
WebSocket中心跳机制的作用主要有以下几个方面:
-
保持连接活跃:
WebSocket是一种双向通信协议,一旦建立连接,服务器和客户端之间可以实时传输数据。但由于网络等原因,长时间没有数据传输可能导致连接的关闭。心跳机制通过定期发送心跳包,即使没有实际数据交互,也能保持连接的活跃状态,防止连接被中断。 -
确认服务器存活状态:
通过心跳机制,客户端可以定期向服务器发送心跳包,并等待服务器的响应。如果一段时间内没有收到服务器的响应,客户端可以判断服务器可能出现了故障或断开连接,并根据情况进行相应的处理,如重新连接服务器。 -
优化网络资源利用:
心跳机制可以定时发送较小的数据包,相较于大量数据传输,心跳包的资源占用较小。这有助于减少网络资源的浪费,并提高数据传输效率。 -
错误处理与重连:
通过心跳机制,客户端可以及时检测到连接断开的情况,并进行错误处理和重连操作。在网络环境不稳定或服务器故障的情况下,心跳机制可以帮助客户端更快地恢复与服务器的连接。 -
连接状态监控:
心跳机制可以用于监控WebSocket连接的状态,包括连接建立、断开、异常等状态。这有助于客户端了解连接状态,做出相应的操作。
总体而言,WebSocket中心跳机制的作用是维持连接的稳定性和可靠性,确保连接保持活跃,并及时处理异常情况,提高通信效率和用户体验。
使用:
const webSocketUrl = 'ws://example.com'; // WebSocket服务器地址
const heartBeatInterval = 5000; // 心跳间隔时间,单位为毫秒
let webSocket = null;
let heartBeatTimer = null;
function initWebSocket() {
webSocket = new WebSocket(webSocketUrl);
webSocket.onopen = () => {
console.log('WebSocket连接已建立');
// 建立连接后开始发送心跳包
startHeartBeat();
};
webSocket.onmessage = (event) => {
// 处理服务器发送的消息
console.log('收到服务器消息:', event.data);
};
webSocket.onclose = () => {
console.log('WebSocket连接已关闭');
// 连接关闭后停止心跳包
stopHeartBeat();
// 可根据需要重新连接
// reconnect();
};
}
function startHeartBeat() {
// 每隔一段时间发送心跳包
heartBeatTimer = setInterval(() => {
if (webSocket.readyState === WebSocket.OPEN) {
webSocket.send('ping'); // 发送心跳包
}
}, heartBeatInterval);
}
function stopHeartBeat() {
// 停止心跳包发送
clearInterval(heartBeatTimer);
}
// 初始化WebSocket连接
initWebSocket();
案例
实现一个简易的聊天功能
1.创建一个文件夹
2.初始化
npm init -y
npm install websocket
3.创建websocket服务端,命名为server.js
const websocket=require("websocket").server
const http=require('http');
const httpServer = http.createServer().listen(8080, ()=>{
console.log('cyl: ','http://localhost:8080');
})
const websocketServer = new websocket({
httpServer: httpServer,
autoAcceptConnections: false
})
const conArr = []
websocketServer.on('request', function(request) {
// 这就是一次客户端发送的消息
// websocket 需要将这个链接保存起来
// 只要客户端和服务器没有断开,这个链接必须在
// 客户端与服务端的通信都是从这个链接上通信
const connection = request.accept()
// 每次接收一个链接,将它存放在数组里面
conArr.push(connection)
console.log(connection)
// 监听客户端发送的消息
connection.on('message', function(message) {
console.log(message);
// 发送消息给客户端(广播到各个客户端)
// 后面加上 utf8Data 编码
// 要将所有的链接全部发出去,才可以让每个客户端接收到其他传来的数据
for(let i = 0; i < conArr.length; i++) {
conArr[i].send(message.utf8Data)
}
})
})
4.创建传送给客户端的文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 需要一进入浏览器就要建立链接 -->
<!-- 点击按钮发送消息给服务器 -->
输入姓名:<input type="text" id="uName">
<br>
输入消息:<input type="text" id="context">
<button id="btn"> 点击发送消息 </button>
<div id="charRoom"></div>
<script>
// 用户名
const uName = document.getElementById('uName')
// 文本框内容
const context = document.getElementById('context')
// 点击按钮
const btn = document.getElementById('btn')
// 要显示聊天室的区域
const charRoom = document.getElementById('charRoom')
// 实例化 websocket
// 必须加 'ws://localhost:8080' ws 协议,后面是开启的服务端接口
const websocket = new WebSocket('ws://localhost:8080')
// 打开事件
websocket.onopen = function() {
// 获取当前链接的状态
// 1 是建立了链接
console.log(websocket.readyState);
}
// 点击发送消息的事件
btn.onclick = function() {
// 将用户名和要发送的内容放在一个对象中,一起传送给后端
const values = {
uName: uName.value,
context: context.value
}
// 清空文本框的内容
uName.value = ''
context.value = ''
// 通过 websocket发送消息
websocket.send(JSON.stringify(values))
}
// 接收服务器返回的消息
websocket.onmessage = function(data) {
console.log("服务器返回的数据",data)
// 服务器返回过来的聊天信息
const chatS = JSON.parse(data.data)
// 添加到页面上
charRoom.innerHTML += `
<strong>${chatS.uName}:</strong>
<span>${chatS.context}</span>
<br />
`
}
// 服务器断开连接,客户端会触发
websocket.onclose = function() {}
</script>
</body>
</html>
4.启动服务端文章来源:https://www.toymoban.com/news/detail-610623.html
node server.js
服务启动成功
文章来源地址https://www.toymoban.com/news/detail-610623.html
到了这里,关于即时通信的方法和webSocket的具体使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!