微建站程序有哪些手机建站
前言
之前遇到过需要即时通讯的场景,刚开始使用的是通过轮询的方式,定时器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.启动服务端
node server.js
服务启动成功