前言:
本篇是用了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 = 8080const TYPE_ENTER = 0const TYPE_EXIT = 1const TYPE_MSG = 2// 聊天室需求:// 01-能多个用户登录,每一个connect对象表示一个用户接入// 02-用户进入(离开)聊天室后,系统广播用户进入(离开)聊天室// 03-某个用户发言,消息传给服务器,服务器再广播给聊天室内的人// 04-定义用户的三个状态,每个状态传给客户端展示不同的消息颜色:// 进入聊天室为0,退出聊天室为1,用户发送消息为2// count定义为用户的数量let count = 0const 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反序列化后端传过来的JSONlet 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.valuews.send(value)console.log("发送成功");// 发送完成清空发送框input.value = null})</script></html>
3.页面展示
用户进入房间
用户间发送消息
用户退出房间
用户3和用户1分别退出房间
