在nodejs中使用WebSocket实现聊天效果(简易实现)
安装
npm i ws
实现
创建 server.js
/**
* 创建一个 WebSocket 服务器,监听指定端口,并处理客户端连接和消息。
*
* @param {Object} WebSocket - 引入的 WebSocket 模块,用于创建 WebSocket 服务器。
*
* 功能步骤:
* 1. 创建一个 WebSocket 服务器,监听端口 1024。
* 2. 维护一个消息列表 `list`,用于存储客户端发送的消息。
* 3. 当客户端发送消息时,解析消息内容并将其添加到消息列表中。
* 4. 将更新后的消息列表发送回客户端。
*/
const WebSocket = require('ws')
// 消息列表,用于存储所有客户端发送的消息
let list = []
// 创建 WebSocket 服务器,监听端口 1024
const wss = new WebSocket.Server(
{
port: 1024
},
() => {
console.log('Server is listening on port 1024')
}
)
// 监听客户端连接事件
wss.on('connection', function (ws) {
// 监听客户端发送的消息事件
ws.on('message', function (msg) {
// console.log('收到客户端消息', JSON.parse(msg))
try {
// 解析客户端发送的消息
if (msg) {
// 如果消息没有错误,将消息内容添加到消息列表中
list.push(JSON.parse(msg).netName + ' 说: ' + JSON.parse(msg).msg)
}
} catch (error) {}
// 将更新后的消息列表发送回客户端
ws.send(JSON.stringify(list))
})
})
创建 client.js 测试
/**
* 创建一个WebSocket客户端,用于连接指定的WebSocket服务器。
*
* 参数:
* - 'ws://192.168.8.183:1024': WebSocket服务器的URL地址。
*/
const WebSocket = require('ws')
const ws = new WebSocket('ws://192.168.8.183:1024')
// 当WebSocket连接成功打开时触发
ws.on('open', function () {
console.log('Client is listening on port 1024') // 打印日志,表示客户端已成功连接到服务器
ws.send(JSON.stringify('Hello World')) // 向服务器发送消息
})
// 当接收到服务器发送的消息时触发
ws.on('message', function (msg) {
console.log('收到服务器消息', JSON.parse(msg))
// ws.send(msg) // 将接收到的消息原样返回给服务器
})
// 当WebSocket连接关闭时触发
ws.on('close', function () {
console.log('Client close') // 打印日志,表示客户端连接已关闭
})
分别运行以上两个文件,如果互相能收到消息表示服务运行正常
创建 index.html 文件
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>WebSocket 消息发送</title>
<style>
/* 消息输入框样式 */
#text {
width: 350px;
height: 30px;
}
/* 用户名输入框样式 */
#netName {
width: 150px;
height: 30px;
}
</style>
</head>
<body>
<!-- 消息显示区域 -->
<textarea id="msg" cols="80" rows="30" readonly></textarea><br />
<!-- 用户名输入框 -->
<input id="netName" type="text" placeholder="名称" />
<!-- 消息输入框 -->
<input id="text" type="text" placeholder="消息" />
<!-- 发送按钮 -->
<button id="sendButton">发送</button>
<script>
let ws = null // WebSocket 连接对象
/**
* 初始化 WebSocket 连接
*/
function initWebSocket() {
if (ws) return // 避免重复连接
ws = new WebSocket('ws://192.168.8.183:1024')
ws.onopen = () => {
console.log('WebSocket 连接已建立')
}
ws.onmessage = (evt) => {
try {
const receivedData = JSON.parse(evt.data)
msg.value = Array.isArray(receivedData) ? receivedData.join('\n') : JSON.stringify(receivedData, null, 2)
} catch (error) {
console.error('解析接收到的数据失败:', error)
}
}
ws.onerror = (error) => {
console.error('WebSocket 错误:', error)
}
ws.onclose = () => {
console.log('WebSocket 连接已关闭,尝试重新连接...')
ws = null
setTimeout(initWebSocket, 5000) // 5 秒后重连
}
setInterval(() => {
ws.send('')
}, 1000)
}
/**
* 发送消息到 WebSocket 服务器
* @param {Object} data - 要发送的数据对象
*/
function sendMessage(data) {
if (!ws || ws.readyState !== WebSocket.OPEN) {
console.warn('WebSocket 未打开,尝试重新连接...')
initWebSocket()
return
}
if (!data) {
data = { err: 1 }
} else if (typeof data !== 'object' || Array.isArray(data)) {
console.error('数据格式无效')
return
}
ws.send(JSON.stringify(data))
}
/**
* 处理发送按钮点击或回车键事件
*/
function handleSend() {
const netNameValue = netName.value.trim()
const textValue = text.value.trim()
if (!netNameValue || !textValue) {
alert('用户名和消息不能为空')
return
}
const message = {
netName: netNameValue,
msg: textValue
}
sendMessage(message)
text.value = '' // 清空消息输入框
}
// 初始化 WebSocket 连接
initWebSocket()
// 绑定发送按钮点击事件
document.getElementById('sendButton').addEventListener('click', handleSend)
// 监听回车键事件
document.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
handleSend()
}
})
</script>
</body>
</html>
用两个浏览器打开此文件,就可以互相发送消息