基于WebSocket实现聊天室(Node)
WebSocket是基于TCP的长连接通信协议,服务端可以主动向前端传递数据,相比比AJAX轮询服务器,WebSocket采用监听的方式,减轻了服务器压力
本文作为学习websocket的练习,实现在线聊天的功能
服务端
server.js
const http = require('http')
const fs = require('fs')
const ws = require('ws')// 创建服务
let server = http.createServer(function (req, res) {res.writeHead(200, {'Content-Type': 'text/html;charset=utf8'})// 显示页面内容fs.readFile("index.html", function (err, data) {if (err)return console.error(err);res.end(data)});
}).listen(8000)// 服务端定义web socket server
let wss = new ws.Server({server})// 存放socket
let clientMap = {}// 计数器
let count = 0// 客户id
let id = 0
let d = new Date()// 客户端连接服务端时,回调函数会接受一个socket对象
wss.on("connection", function (socket) {count ++;id ++;// 添加用户socket.id = idclientMap[id] = socketconsole.log("第" + count + "位用户上线了,ID为" +id)socket.send("欢迎来到聊天室,已经有"+count+"位用户在线")// 监听客户端数据socket.on("message", function (msg) {// 广播消息for(let id in clientMap){console.log(id)console.log(socket.id)if(id === socket.id.toString())clientMap[id].send(d.toLocaleTimeString() + " 我: "+ msg)elseclientMap[id].send(d.toLocaleTimeString() + " " + socket.id +"号: "+ msg)}})// 监听客户下线socket.on("close", function (e) {// 删除用户count --;console.log(socket.id + "号用户" + "下线")delete clientMap[socket.id]})// 错误连接socket.on("error", function (err) {console.log("客户连接错误" + err)})
})
客户端
index.html
<!DOCTYPE html>
<html lang="en"><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>聊天室</title><style>#room {border: solid;margin: 2px;width: 400px;height: 500px;overflow-y: scroll;}</style></head><body><div id="room"></div><input type="text" id="msg"><button id="send">发送</button><!--客户端脚本--><script>// 定义web socket clientlet wsc = new WebSocket("ws://localhost:8000")let serverError = falselet room = document.getElementById("room")let inputText = document.getElementById("msg")// 建立连接wsc.onopen = function (e) {console.log('成功进入聊天室')}// 获取后端消息wsc.onmessage = function (e) {room.innerHTML +='<p>'+e.data+'</p>'}// 关闭wsc.onclose = function (e) {alert("聊天室已经关闭")serverError = true}// 错误wsc.onerror = function () {console.log("连接错误")}// 发送信息sendMsg = function () {let s = inputText.valueif (serverError) {alert("聊天室已经关闭")}else if (msg.value === "") {// alert("发送内容不能为空")} else {wsc.send(s)inputText.value = ""}}// 注册发送信息的事件send.onclick = sendMsgdocument.onkeydown = function(evt){if(evt.code === "Enter")sendMsg()};</script>
</body>
</html>
运行结果
运行
$ node server.js
开启不同浏览器,或同一浏览器的多个tab,访问localhost:8000,就可以实习聊天功能
服务端输出:
$ study node server.js
第1位用户上线了,ID为1
第2位用户上线了,ID为2
第3位用户上线了,ID为3
3号用户下线
2号用户下线
1号用户下线
小结
感觉Websocket非常优雅,后端变得主动才好嘛~