之前遇到过需要即时通讯的场景,刚开始使用的是通过轮询的方式,定时器3秒向服务器请求一次数据,后面发现如果在手机端长时间打开使用此功能的页面,可能会发生手机发热,甚至卡顿的现象。最后改用webSocket,可以实现全双工通信,让服务器主动向客户端发送请求。
接下来先介绍一下即时通信的实现方法?
轮询(Polling):
长轮询(Long Polling):
WebSocket:
Server-Sent Events(SSE):
EventSource
对象订阅服务器的事件流,一旦有新数据可用,服务器会自动发送数据给客户端。在前端中使用 WebSocket 非常简单,首先需要在浏览器中创建一个 WebSocket 对象,然后通过该对象与服务器建立连接。一旦连接建立成功,前端可以通过发送和接收消息来实现与服务器的实时通信。
在 JavaScript 中,可以通过以下代码创建 WebSocket 对象:
const socket = new WebSocket('ws://example.com'); // 根据实际情况替换为服务器的 WebSocket 地址
在上述代码中,我们创建了一个 WebSocket 对象,传入服务器的 WebSocket 地址作为参数。WebSocket 地址的协议可以是 ws
(未加密)或 wss
(加密)。
一旦 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
事件(连接错误)。每当相应的事件触发时,我们通过回调函数来处理相应的逻辑。
一旦 WebSocket 连接建立成功,就可以通过 send()
方法来发送消息,同时通过 onmessage
事件来接收消息。
// 发送消息
socket.send('Hello, WebSocket!');
// 接收消息在上面的监听代码中已经处理
以上代码演示了如何在前端中创建 WebSocket 连接、发送和接收消息。当服务器和客户端建立连接后,它们可以随时通过 send()
方法和 onmessage
事件来实现实时通信。
实现一个简易的聊天功能
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>Documenttitle>
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 += `
${chatS.uName}:
${chatS.context}
`
}
// 服务器断开连接,客户端会触发
websocket.onclose = function() {}
script>
body>
html>
4.启动服务端
node server.js