一、简介
-
nodejs端安装WebSocket$ npm install ws
二、node 端基本部署
-
在入口文件中写入调试即可。
-
简单版本,只想让
WebSocket服务器单独运行,可以直接创建一个WebSocket服务器,不需要传入server对象。const WebSocket = require('ws'); // 创建 WebSocket 服务器,不传入 HTTP 服务器 const wss = new WebSocket.Server({ port: 8080 }); // 监听客户端连接 wss.on('connection', (ws) => { console.log('A new client connected!'); // 监听客户端消息 ws.on('message', (message) => { console.log(`Received message: ${message}`); // 向客户端发送响应 ws.send('Message received'); }); // 向客户端发送初始欢迎消息 ws.send('Welcome to the WebSocket server!'); }); console.log('WebSocket server is running on ws://localhost:8080'); -
需要支持
http服务,也就是额外的接口路由服务,使用默认自带的:const WebSocket = require('ws'); const http = require('http'); // 创建一个 HTTP 服务器,托管静态文件 const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end('<h1>WebSocket Server Running</h1>'); }); // 创建 WebSocket 服务器,并将其绑定到 HTTP 服务器 // 这样就可以将 WebSocket 与 server.listen 绑定为一个端口 const wss = new WebSocket.Server({ server }); // 监听客户端连接 wss.on('connection', (ws) => { console.log('A new client connected!'); // 监听来自客户端的消息 ws.on('message', (message) => { console.log(`Received message: ${message}`); // 向客户端发送响应 ws.send('Message received'); }); // 向客户端发送初始欢迎消息 ws.send('Welcome to the WebSocket server!'); }); // 启动 HTTP 服务器并监听端口 server.listen(8080, () => { console.log('Server is running at http://localhost:8080'); }); -
还有就是使用第三方库,例如
express之类的库:const express = require('express'); const http = require('http'); const WebSocket = require('ws'); // 创建 Express 应用 const app = express(); // 创建 HTTP 服务器并将其与 Express 连接 const server = http.createServer(app); // 创建 WebSocket 服务器,并将其绑定到现有的 HTTP 服务器 const wss = new WebSocket.Server({ server }); // 监听 WebSocket 客户端连接 wss.on('connection', (ws) => { console.log('A new client connected!'); // 监听客户端发送的消息 ws.on('message', (message) => { console.log(`Received message: ${message}`); // 向客户端发送响应 ws.send('Message received'); }); // 向客户端发送初始欢迎消息 ws.send('Welcome to the WebSocket server!'); }); // 在 Express 中定义一些 HTTP 路由 app.get('/', (req, res) => { res.send('<h1>Hello from Express</h1>'); }); // 启动 HTTP 和 WebSocket 服务器 server.listen(8080, () => { console.log('Server running at http://localhost:8080'); }); -
选择自己的一种方式配置好后,运行
node项目即可。
三、客户端基本部署
-
在现代浏览器中,
WebSocket是原生支持的,不需要引入额外的CDN或第三方库。因此,可以直接在客户端的JavaScript代码中使用WebSocket对象,无需额外的外部依赖。 -
直接创建一个
index.html网页,写入代码打开即可,本地用的是localhost,线上记得根据实际情况进行更换调整。<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>WebSocket Client</title> </head> <body> <h1>WebSocket Test</h1> <button id="sendBtn">Send Message to Server</button> <div id="response"></div> <script> // 创建 WebSocket 连接到 Node.js WebSocket 服务器 const socket = new WebSocket('ws://localhost:8080'); // 打开连接时的回调 socket.addEventListener('open', () => { console.log('Connected to WebSocket server'); socket.send('Hello, server!'); }); // 监听来自服务器的消息 // socket.addEventListener('message', (event) => { // const responseDiv = document.getElementById('response'); // responseDiv.textContent = 'Server says: ' + event.data; // console.log('Message from server: ' + event.data); // }); // 监听来自服务器的消息,这种写法跟上面的写法效果是一样的,其他监听方法也同理 // 例如上面的 open 监听,下面的 close 都一样,前面加个 on 即可(socket.onclose、socket.onopen)。 socket.onmessage = (event) => { const responseDiv = document.getElementById('response'); responseDiv.textContent = 'Server says: ' + event.data; console.log('Message from server: ' + event.data); }; // 监听连接关闭事件 socket.addEventListener('close', () => { console.log('Connection closed'); }); // 监听连接错误事件 socket.addEventListener('error', (error) => { console.error('WebSocket Error: ' + error); }); // 发送消息到服务器按钮 const sendBtn = document.getElementById('sendBtn'); sendBtn.addEventListener('click', () => { socket.send('Sending message from client'); }); </script> </body> </html>这样就接通了,就可以根据规则进行使用了。
四、心跳模式
-
不使用心跳机制可能导致的问题:
-
连接被断开:防火墙、
NAT、路由器等设备可能会因长时间无数据流动而断开连接。 -
无法及时检测断开连接:如果没有心跳机制,可能无法及时得知连接断开。
-
丢失连接:由于网络问题,可能导致连接丢失,而没有心跳机制无法及时检测并恢复连接。
-
服务器端或客户端因超时断开连接:服务器可能会因为空闲时间过长而自动断开连接。
建议:对于长时间运行的
WebSocket连接,特别是在可能遇到中间网络设备干扰的情况下,使用心跳机制是一个非常好的实践。这可以帮助确保连接活跃、检测断开,并且让应用更加健壮和稳定。
-
-
node 端const express = require('express') const http = require('http'); const path = require('path') const app = express() const WebSocket = require('ws'); // 创建 HTTP 服务器并将其与 Express 连接 const server = http.createServer(app); // 创建 WebSocket 服务器,并将其绑定到现有的 HTTP 服务器 const wss = new WebSocket.Server({ server }); // 监听 WebSocket 客户端连接,每个新的连接都是一个独立的处理对象,所以不会造成阻塞 wss.on('connection', (ws, req) => { // 获取原始 IP 地址 const ip = req.socket.remoteAddress; // 转换 IPv6 回环地址 (::1) 为 IPv4 的 127.0.0.1 // ::1 是 IPv6 中的回环地址,等价于 IPv4 中的 127.0.0.1,这表示客户端和服务器运行在同一台机器上(本地连接)。 const normalizedIp = ip === '::1' ? '127.0.0.1' : ip.replace('::ffff:', ''); console.log('New client connected from IP:', ip, 'NormalizedIp:', normalizedIp); // 设置心跳(定时发送 pong)当客户端长时间没有发送 ping 消息时,可以自行发送心跳 // const heartbeatInterval = setInterval(() => { // // 发送 pong 消息 // if (ws.readyState === WebSocket.OPEN) { // ws.send('pong'); // pong 消息 // } // }, 30000); // 每 30 秒发送一次 ping // 监听客户端发送的消息 ws.on('message', (message) => { // 如果 message 是 Buffer,转换为字符串 if (Buffer.isBuffer(message)) { message = message.toString(); console.log('Received message from client:', message); // 向客户端发送响应 // ws.send('Message received') // 如果收到 ping 消息,回复 pong 消息 if (message === 'ping') { console.log('Sending pong to client'); // 响应发送 pong 消息 ws.send('pong'); } } else { console.log('Received message from client:', message); } }) // 连接关闭时清理定时器 ws.on('close', () => { // clearInterval(heartbeatInterval); console.log('Client disconnected') }) // 向客户端发送初始欢迎消息 ws.send('Welcome to the WebSocket server!') }) // 设置静态页面,默认就是 '/' 路由 app.use(express.static(path.join(__dirname, 'public'))); // 处理未匹配到的路由,返回 404 页面 app.use((req, res) => { res.status(404).sendFile(path.join(__dirname, 'public/404.html')) }) // 启动 HTTP 和 WebSocket 服务器 server.listen(8080, () => { console.log('Server running at http://localhost:8080'); }); -
客户端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> html, body { width: 100%; height: 100%; } html, body, ul, li, dl, dt, dd { margin: 0; padding: 0; } .container { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; } </style> </head> <body> <div class="container"> <!-- <button id="send">发送消息</button> --> <h1>WebSocket Test</h1> <button id="sendBtn">Send Message to Server</button> <div id="response"></div> <script> // 创建 WebSocket 连接到服务器 const socket = new WebSocket('ws://localhost:8080'); // 当连接建立时 socket.onopen = () => { console.log('Connected to the WebSocket server'); // 设置心跳(每隔 30 秒发送一次 ping) setInterval(() => { if (socket.readyState === WebSocket.OPEN) { socket.send('ping'); // 向服务器发送 ping } }, 30000); }; // 处理消息 socket.onmessage = (event) => { const responseDiv = document.getElementById('response'); responseDiv.textContent = 'Server says: ' + event.data; console.log('Message from server: ' + event.data); // 如果收到 pong 响应,代表服务器响应了心跳 if (event.data === 'pong') { console.log('Received pong from server'); } }; // 连接关闭时的回调 socket.onclose = () => { console.log('Disconnected from the WebSocket server'); }; // 发送消息到服务器按钮 const sendBtn = document.getElementById('sendBtn'); sendBtn.addEventListener('click', () => { socket.send('Sending message from client'); }); </script> </div> </body> </html>