express使用webSocket

#webSocket的特点
websocket的特点之一是可以双向发数据,例如聊天场景,双方通信都是实时的,传统解决方案是使用轮询,即每一段时间发送一次请求给服务器,但是这种方式的缺点是占用资源,而websocket是协议层面的改变,让服务器可以向客户端主动发送消息,原理可以参考:
https://www.ruanyifeng.com/blog/2017/05/websocket.html
协议抓捕可以参考
https://www.likecs.com/show-662366.html

这里使用socket.io,实现一个聊天的Demo
后端:

let express = require("express");
let socket = require("socket.io");
let http = require("http");
let fs = require("fs")
let server = express()

// 静态化
server.use(express.static("./web/"))


let app = http.createServer(server);

let io = socket(app)
let usermsgs = [];
let users = []
io.on("connection", (client) => {
    fs.readdir("./web/images", (err, result) => {

        if (!err)
            client.emit("Msg", 0, result)

        } else {
            client.emit("Msg", 1, "目录读取失败")
        }
    })
    // 监听客户端加入
    client.on("Newclient", (username) => {
        // 1.存储用户
        users.unshift([username.username, client]) // 存储用户名和当前客户端对象

        // 2.广播消息 告诉其他用户,这个用户进入了俩天

        io.emit("userlist", {
            userlist: users.map(item => item[0])
        })

        //   console.log("新加入", users.map(item => item[0]))
    })

    // 监听客户端离开


    client.on("disconnect", () => {

        // 1.删除用户

        // users.indexOf([username.username, client])
        let index = users.findIndex((item) => {
            if (item[1] === client)
                return true
        })
        if (index !== -1)
            users.splice(index, 1) // 删除index
        // 2.广播消息 告诉其他用户,这个用户进入了俩天

        io.emit("userlist", {
            userlist: users.map(item => item[0])
        })

        ///  console.log("删除后", users.map(item => item[0]));

    })
    //监听客户端的文本消息
    client.on("uerMsg", (...args) => {

        console.log("消息", args[0], typeof args[0])
        // 存消息

        let newargs = args[0].replace(/\[(\w+)\]/gm, (...arge) => {

            console.log("args", arge);
            return ` <img src="/images/${arge[1]}.png" alt="" class="item">`;

        })

        usermsgs.push([newargs, args[1], , client])
        // 公告消息
        io.emit("userMsgs", usermsgs.map(item => [item[0], item[1]]))

    })


})

app.listen(3000, () => console.log("服务器启动成功"))

其中 io.on(“connection” ,) 这个是表示监听链接的客户端,是内置的事件
client.on(“disconnect”,)这个表示监听客户端离开,是内置事件
其他的on监听事件,是自定义的和客户端相对应
前端:
io.emit(“userMsgs”, usermsgs.map(item => [item[0], item[1]])) 表示广播给所有客户端

  <script src="/socket.io/socket.io.js"></script>
    <script>
        // 发送socket请求
        let socket = io();
        // 监听浏览器与服务器连接
        socket.on("connect", function (...args) {

            // 连接成功后就直接
            let username = prompt("请输入用户名") || "匿名用户";
            document.querySelector(".username").innerHTML = `<h1>${username}</h1>`

            // 发送消息
            socket.emit("Newclient", {
                "username": username
            })

            btn.addEventListener("click", (e) => {
                // console.log(text.value)
                if (text.value.length > 0) {
                    socket.emit("uerMsg", text.value, username)
                } else {
                    alert("没有输入内容")
                }
            })

        })
        // 监听消息 写咋连接的外面
        socket.on("Msg", (...args) => {

            let str = "";
            for (let i = 0; i < args[1].length; i++) {
                str += `<img src="/images/${args[1][i]}" alt="" class="item">`
            }
            document.querySelector(".img-list").innerHTML = str;
            // 给每一个图片设置一个点击事件
            let imgs = document.querySelectorAll(".item")
            for (let i = 0; i < imgs.length; i++) {
                imgs[i].addEventListener("click", () => {

                    //console.log(imgs[i].src.match(/\/(\w+)\./));

                    text.value += `[${imgs[i].src.match(/\/(\w+)\./)[1]}]`

                })

            }

        })
        //监听人数


        // 监听消息 连接可以写在外面
        socket.on("userlist", (args) => {
            console.log(args)
            let str = "";
            for (let i = 0; i < args.userlist.length; i++) {
                str += `<li class="list-group-item">${args.userlist[i]}</li>`
            }
            console.log("xx", str)
            document.querySelector(".userlist").innerHTML = str;


        })

        // 监听用户消息

        socket.on("userMsgs", (args) => {

            console.log("全部用户消息", args)
            let str = "";
            for (let i = 0; i < args.length; i++) {
                str += `<li class="list-group-item">${args[i][1]} : ${args[i][0]}</li>`
            }
            // console.log("xx", str)
            document.querySelector(".ly").innerHTML = str;



        })
    </script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值