前言:
本篇是用了nodejs-websocket来实现服务端的socket服务器的,比较偏向于原生,后面有时间再去研究socket.IO框架。这个聊天室比较简陋,只实现了最基本的功能,结构和代码都比较简单。
nodejs-websocket
1.构建websocket的node服务端
(1)安装nodejs-websocket
npm install nodejs-websocket —save
(2)编写服务端代码
这里直接给了,比较简单,可以直接看注释
聊天室需求: 01-能多个用户登录,每一个connect对象表示一个用户接入 02-用户进入(离开)聊天室后,系统广播用户进入(离开)聊天室 03-某个用户发言,消息传给服务器,服务器再广播给聊天室内的人 04-定义用户的三个状态,每个状态传给客户端展示不同的消息颜色: 进入聊天室为0, 退出聊天室为1, 用户发送消息为2
const ws = require("nodejs-websocket")
const PORT = 8080
const TYPE_ENTER = 0
const TYPE_EXIT = 1
const TYPE_MSG = 2
// 聊天室需求:
// 01-能多个用户登录,每一个connect对象表示一个用户接入
// 02-用户进入(离开)聊天室后,系统广播用户进入(离开)聊天室
// 03-某个用户发言,消息传给服务器,服务器再广播给聊天室内的人
// 04-定义用户的三个状态,每个状态传给客户端展示不同的消息颜色:
// 进入聊天室为0,退出聊天室为1,用户发送消息为2
// count定义为用户的数量
let count = 0
const server = ws.createServer((connect) => {
// 新用户连接时触发
{
console.log("新用户连接成功");
// 用户数量加一
count++
connect.name = `用户${count}`
// 用户名最初时发给用户,后面不再发送
connect.sendText(JSON.stringify({
type: "name",
username: connect.name
}))
// 用户进入聊天室了,系统广播一次
let enterMsg = JSON.stringify(createMsg(TYPE_ENTER, `${connect.name}进入了聊天室`))
broadcast(enterMsg)
}
// 当用户传入数据时,text事件会被触发
connect.on("text", (msg) => {
console.log("收到消息:", msg);
// connect.sendText(msg)
// 有用户发送消息了,广播给聊天室每一个用户
let userMsg = JSON.stringify(createMsg(TYPE_MSG, `${connect.name}:${msg}`))
broadcast(userMsg)
})
// 注册close,用户连接断开时自动触发(用户关闭页面)
connect.on("close", () => {
// 用户退出聊天室了,系统广播一次
let exitMsg = JSON.stringify(createMsg(TYPE_EXIT, `${connect.name}退出了聊天室`))
broadcast(exitMsg)
console.log("连接断开啦!!!");
})
// 注册error,处理用户的错误信息(连接断开时会有错误处理)
connect.on("error", () => {
console.log("连接异常");
})
})
// 广播函数
function broadcast(msg) {
server.connections.forEach(function (connect) {
connect.sendText(msg)
})
}
// 返回的消息对象
function createMsg(type, content) {
return {
type,
content,
time: new Date().toLocaleDateString()
}
}
server.listen(PORT, () => {
console.log("websocket服务启动成功,监听端口:", PORT);
})
2.客户端H5代码的编写
<!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>WebSocket</title>
<style>
.msg-box {
width: 30rem;
height: 30rem;
margin-top: .5rem;
padding: .5rem;
border: 1px solid brown;
border-radius: .5rem;
font-size: 1.2rem;
}
</style>
</head>
<body>
<h2 class="username"></h2>
<!-- 输入消息 -->
<input type="text" placeholder="输入要发送的消息" />
<!-- 发送消息 -->
<button class="sendMsg">发送消息</button>
<!-- 退出聊天室 -->
<button class="exitRoom">退出聊天室</button>
<!-- 接收消息框 -->
<div class="msg-box"></div>
</body>
<script>
let username = document.querySelector(".username")
let input = document.querySelector("input")
let sendMsg = document.querySelector(".sendMsg")
let exitRoom = document.querySelector(".exitRoom")
let msgBox = document.querySelector(".msg-box")
// 01-创建一个WebSocket对象(这个服务地址,你发送什么,他就返回什么)
let ws = new WebSocket("ws://localhost:8080")
// 02-onopen,与websocket服务器连接成功时触发
ws.addEventListener('open', () => {
console.log('websocket connect is open');
})
// 03-onmessage,监听服务器传入的数据,服务器发送消息时触发
ws.addEventListener('message', (e) => {
// JSON.parse反序列化后端传过来的JSON
let data = JSON.parse(e.data)
// 判断data.type是否是用户名
if (data.type === "name") {
// 是用户名,显示给用户
username.innerHTML = data.username
} else {
// 不是用户名,则解析消息数据
let { name, type, content, time } = data
// 每条消息创建一个div插入到box内
let newMsg = document.createElement("div")
newMsg.innerHTML = `${content} - ${time}`
// 判断消息的类型,来转变不同的颜色
if (type === 0) {
newMsg.style.color = "green"
} else if (type === 1) {
newMsg.style.color = "red"
} else {
newMsg.style.color = "skyblue"
}
msgBox.appendChild(newMsg)
}
})
// 退出聊天室
exitRoom.addEventListener('click', () => {
// 04-close()关闭websocket连接
ws.close()
console.log("websocket connect is close");
})
// 向服务端发送信息
sendMsg.addEventListener('click', () => {
let value = input.value
ws.send(value)
console.log("发送成功");
// 发送完成清空发送框
input.value = null
})
</script>
</html>
3.页面展示
用户进入房间
用户间发送消息
用户退出房间
用户3和用户1分别退出房间