基于WebSocket实现聊天室(Node)

Posted 潇雨危栏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于WebSocket实现聊天室(Node)相关的知识,希望对你有一定的参考价值。

基于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 = id
    clientMap[id] = socket
    console.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)
            else
                clientMap[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 client
        let wsc = new WebSocket("ws://localhost:8000")
        let serverError = false
        let 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.value
            if (serverError) {
                alert("聊天室已经关闭")
            }
            else if (msg.value === "") {
    //            alert("发送内容不能为空")
            } else {
                wsc.send(s)
                inputText.value = ""
            }
        }

        // 注册发送信息的事件
        send.onclick = sendMsg
        document.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非常优雅,后端变得主动才好嘛~

以上是关于基于WebSocket实现聊天室(Node)的主要内容,如果未能解决你的问题,请参考以下文章

Node + H5 + WebSocket + Koa2 实现简单的多人聊天

node实现websocket聊天室

Node.js+websocket+mongodb实现即时聊天室

ws模块指南+Vue在线聊天室

[已解决]基于WebSocket开发聊天室应用

基于flask框架,使用websocket实现一对一聊天室功能