简单的实现webSocket多人实时群聊

webSocket 即时刷新页面消息

  • 前言

http协议它有局限性,服务器不能单方面向客户端发送消息
在以往的开发中,这种想即时通讯,用的都是轮询 以及长连接
webSocket 它的优势就是服务端推送消息

话不多说先上代码
代码内各行功能性代码都有注释

  • 服务端

/*
    服务端代码
*/

const ws = require('ws'); // 引入ws模块
// 创建ws服务器,并设置端口号为9000
let wsServer = new ws.Server({
    port: 9000
})
// 监听客户端的接入
wsServer.on('connection', connection);
// 客户端接入的事件处理函数

function connection(socket) {
    // 监听客户端发送消息
    socket.on('message', msg => {
        let data = JSON.parse(msg)
        //判断接受消息的类型
        switch (data.type) {
            case 'login': //新用户加入
                socket.nickname = data.username //保存用户名属性
                broadcast(
                    //发送json字符串告诉客户端有新用户加入
                    JSON.stringify({
                        username: data.username,// 用户的名字
                        time: getTime(), // 发表的时间
                        type: data.type // 类型
                    })
                )
                break
            case 'msg':
                //发送json字符串告诉客户端有新用户加入
                broadcast(
                    JSON.stringify({
                        username: data.username, // 用户的名字
                        time: getTime(), // 发表的时间
                        message: data.message, //用户发表的内容
                        type: data.type // 类型
                    })
                )
                break
        }
    })
    //监听错误信息
    socket.on('error', (err) => {
        console.log(err)
    })
    //监听断开连接
    socket.on('close', () => {
        broadcast(
            JSON.stringify({
                username: socket.nickname, // 用户的名字
                time: getTime(), // 离开的时间
                type: 'leave' // 离开的类型
            })
        )
    })
}


//给所有连接的客户端发送消息
function broadcast(str) {
    //遍历所有连接的客户端
    wsServer.clients.forEach((conn) => {
        //发送消息
        conn.send(str)
    })
}


function getTime() {
    var date = new Date();
    var hour = date.getHours();
    var min = date.getMinutes()
    var sec = date.getSeconds()
    min = min < 10 ? "0" + min : min
    sec = sec < 10 ? "0" + sec : sec
    return hour + ":" + min + ":" + sec
}
  • 客户端

/*
    客户端代码
*/

//获取button对象
let addBtn = document.getElementById("addBtn")  // 加入按钮
let sendBtn = document.getElementById("sendBtn") // 发送按钮
let username = document.getElementById("username") // 用户名
var message = document.getElementById("message") // 发送的内容

//定义全局
let ws = null;

// 点击添加新用户
addBtn.onclick = function () {
    //调用join函数 创建跟后台的链接
    join()
}

//给用户名文本框添加键盘点击事件
username.onkeyup = function (e) {
    //如果输入的是回车,进聊天室
    if (e.keyCode === 13) {
        //调用join函数 创建跟后台的链接
        join()
        //禁止如数文本内容
        username.disabled = true
    }
}
// 点击发送内容按钮
sendBtn.onclick = function () {
    sendMessage()
}
//给发送内容文本框 添加键盘事件
message.onkeyup = function (e) {
    // keyCode 13 就是回车键
    if (e.keyCode === 13 && !sendBtn.disabled) {
        sendMessage()
    }
}

function join() {
    addBtn.disabled = true  //禁止添加新用户按钮
    username.disabled = true //禁止如数文本内容
    sendBtn.disabled = false //给改变发送内容文本框可以编辑

    // 创建WebSocket对象,WebSocket使用的是ws协议
    ws = new WebSocket('ws://localhost:9000') // localhost就是你起服务的主机IP
    ws.onopen = function () {
        //获取用户名
        let username = document.getElementById("username").value
        // 向服务器端发送消息
        ws.send(
            // 往后台发送json字符串
            JSON.stringify({
                username: username,
                type: 'login' //添加的对象 
            })
        )
    }
    // onmessage与ws已经绑定,接受消息回来的时候还是会回到这里来
    // 服务器发送消息后会触发
    ws.onmessage = function (e) {
        console.log(e.data)
        //字符串对象转json对象
        let data = JSON.parse(e.data)
        let show
        switch (data.type) {
            case 'login': //新用户
                show = `<span class="enter">${data.username}</span>加入了房间`
                break;
            case 'msg': // 有新的聊天信息
                show = `<span class="talk">${data.username}</span> ${data.time} <div>${data.message}</div>`
                break
            case 'leave': //有人离开聊天室
                show = `<span class="leave">${data.username}</span>离开了房间 ${data.time}`
                break;
        }
        //创建 里元素节点
        let li = document.createElement("li")
        li.innerHTML = show
        document.getElementById("msg").append(li)
    }
}


function sendMessage() {
    // 用户名
    let username = document.getElementById("username").value
    // 发送内容
    let msg = document.getElementById("message").value
    //发送聊天消息给服务器
    ws.send(JSON.stringify({
        username: username,
        message: msg,
        type: 'msg'
    }))
    // 发送内容置空
    document.getElementById("message").value = ''
}

  • 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>Document</title>
    <style>
        .enter{
            color:lightgreen;
        }
        .talk{
            color: dodgerblue;
        }
        .leave{
            color: red;
        }
    </style>
</head>

<body>
    <div id="main">
        <p>
            <input type="text" id="username" placeholder="请输入用户名" />
            <button type="button" id="addBtn">加入</button>
        </p>
        <p>
            <input type="text" id="message" placeholder="请输入聊天信息" />
            <button type="button" id="sendBtn" disabled>发送</button>
        </p>
        <ul id="msg"></ul>
    </div>



    <script src="./js/index.js"></script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值