基于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非常优雅,后端变得主动才好嘛~

posted @ 2018-03-18 18:13  潇雨危栏  阅读(425)  评论(0编辑  收藏  举报