express+websocket实现简单的聊天室

编写后台接口

1.引入express 以及 express-ws

```
npm install express express-ws
```

2.编写聊天室接口

简单描述:
1.首先引入ws
2.创建连接
3.每个用户都有一个conn 那把conn存入到数组里方便以后广播所接受到的消息,去传达到其他用户。
4.对用户数量做一个统计
5.接收到前端传来设置的用户名
6.数据格式统一

obj={
	type:'name'|'count'|'message';
	data:''
}

代码如下:

const express = require("express");
const expressWs = require("express-ws");
const router = express.Router();
expressWs(router);

let count = 0;
//存放所有连接的用户
let connections = [];
router.ws('', conn => {
    //每个用户都有一个conn
    count++;
    console.log(`游客进入聊天室,当前在线人数${count}`);
    sendMsg(conn, 'count', count);
    broadcast(JSON.stringify({ type: 'count', data: count }));
    //接收用户发来的数据
    conn.on('message', function(msg) {
            let obj = JSON.parse(msg);
            if (obj.type === 'name') {
                conn.userName = obj.data;
                connections.push(conn);
                console.log(`用户的名字为${conn.userName},当前在线人数${count}`);
                sendMsg(conn, 'name', conn.userName);
                broadcast(JSON.stringify({ type: 'toast', data: `${conn.userName}进入了聊天室` }));
            } else if (obj.type === 'message') {
                broadcast(JSON.stringify({ type: 'message', data: obj.data, userName: conn.userName }))
            }
        })
        //监听关闭状态
    conn.on('close', function() {
        count--;
        broadcast(JSON.stringify({ type: 'count', data: count }));
        broadcast(JSON.stringify({ type: 'toast', data: `${conn.userName}离开了聊天室,当前在线人数${count}` }));
        console.log(`用户:${conn.userName ? conn.userName :'游客'}离开了聊天室,当前在线人数${count}`);
    })
})


function broadcast(msg) {
    // 群发消息给所有用户
    connections.forEach(item => {
        item.send(msg)
    })
}
//单独发送给一个用户
function sendMsg(conn, type, data) {
    conn.send(JSON.stringify({ type: type, data: data }));
}

module.exports = router;

3.设置路由为 /ws/many

const manyWs = require('./many-ws');
app.use('/ws/many', manyWs);

前端逻辑

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码如下:
    btn.onclick = function() {
        userName = userName.value;
        let obj = {
            type: 'name',
            data: userName
        }
        obj = JSON.stringify(obj);
        ws.send(obj);
        namePanel.style.display = 'none';
    }
	//传后台
    ws.onmessage = function(res) {
        let obj = JSON.parse(res.data);
        if (obj.type === 'name') {
            userNameSpan.innerHTML = obj.data;
        } else if (obj.type === 'count') {
            peopleNum.innerHTML = obj.data;
            console.log(obj)
        } else if (obj.type === 'toast') {
            msgCon.innerHTML += addToast(obj.data);
            msgCon.scrollTo({
                top: msgCon.scrollHeight,
                behavior: "smooth",
            });
        } else if (obj.type === 'message') {
            obj.userName === userName ? textHtml('right', obj.data) : textHtml('left', obj.data);
        }

    }

    textarea.onkeyup = function(e) {
        let val = textarea.value;
        if (e.keyCode === 13) {
            if (val.trim() !== "") {
                ws.send(JSON.stringify({
                    type: 'message',
                    data: val
                }));
                textarea.value = '';
            } else {
                tips.style.display = "block";
                setTimeout(() => {
                    tips.style.display = "none";
                }, 1000);
            }
        }
    };

    backBtn.onclick = function() {
        location.href = "http://localhost:3001"
    }

    function addToast(data) {
        return `<div class="panel-toast">${data}</div>`
    }

    function textHtml(position, text) {
        let str = '';
        if (position === "left") {
            str = `<div class="msg msg-${position}">
        <img src="./img/${position==='left'?'dufu':'libai'}.png" alt="">
        <section>
            <span>${text}</span>
            </section>
        </div>;`;
        } else if (position === "right") {
            str = `
        <div class="msg msg-right">
            <section>
                <span>${text}</span>
            </section>
            <img src="./img/libai.png" alt="">
        </div>`;
        }
        msgCon.innerHTML += str;
        msgCon.scrollTo({
            top: msgCon.scrollHeight,
            behavior: "smooth",
        });
    }

小白一个不喜勿喷,样式代码我就不放了,自行设计=-=

猜你喜欢

转载自blog.csdn.net/DragonOfMoon/article/details/125517816
今日推荐