socket.io案例

本文档介绍了一个使用socket.io构建的WebSocket聊天应用。应用包括建立连接、消息分发、在线人数显示等功能。服务端维护在线人数计数,客户端接收并显示消息及在线人数。此外,还涉及到登录和发送消息时携带头像、昵称等参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求如下

1、在聊天界面中建立websocket连接.
2、一个客户端发消息, 服务端接收消息后把消息分发给所有客户端.
3、客户端接收服务端发回来的消息, 打印.(显示在聊天记录区域)
4、提示当前在线人数.
(1)服务端中一旦接收到客户端连接, 维护一个全局变量count, 记录当前在线人数(count++)
(2)当服务端发现有客户端断开连接就需要让(count–)
5、无论count如何变化, 只要count有变化就需要将count实时发给所有客户端.
6、客户端接收服务端发过来的消息countmsg. 将人数实时显示在页面中.
7、登录, 发消息时携带头像/昵称等参数.

完整demo

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./styles/chart.css">
    <link rel="stylesheet" href="./styles/normalize.css">
    <link rel="stylesheet" href="./styles/reset.css">
</head>
<body>
    <div id="chart-container">
        <div class="chart-user-list" id="chart-user-list">
            <div id="userinfo" class="user-item">
                <img src="images/avatar/15.jpg" alt="">              
                未知名
            </div>
        </div>
        <div class="chart-main-area">
            <div class="chart-main-title">
                <h1>微信聊天室(<span id="userNumber"></span>)-<span id="currentUser"></span></h1>
            </div>
            <div class="chart-list" id="chat-list">
                <!-- 
                <div class="user-logined" id="user-logined"><span id="logined-user"></span>上线了</div>
                <div class="chart-item">
                    <div class="user-face"><img src="images/avatar/11.jpg" alt=""></div>
                    <div class="user-message">111</div>
                </div>
                 -->
            </div>
            <div class="chart-form">
                <div><textarea class="chart-form-message" id="message"></textarea></div>
                <div><input type="button" id="send" class="chart-form-send" value="发表"></div>
            </div>
        </div>
    </div>
</body>
<script src="/socket.io/socket.io.js"></script>
    <script>
        //建立websocket连接
        let socket=io()
        console.log(socket);

        //监听服务端发送给客户端的消息,并且输出打印到聊天记录区
        socket.on('news',(data)=>{
            console.log(data);
            //创建一个div,追加到chat-list子元素的末尾
            let div=document.createElement('div')
            //添加类名
            div.className='chart-item'
            div.innerHTML=`<div class="user-face">
                                <img src="images/avatar/${data.avatar}" alt="">
                            </div>
                            <div class="user-name">${data.name}</div>
                            <div class="user-message">${data.msg}</div>`
            //追加到chart-list子元素的末尾
            let chatlist=document.getElementById('chat-list')
            chatlist.appendChild(div)
            //让滚动条始终保存在底部
            chatlist.scrollTop=chatlist.scrollHeight
        })

        //为发表绑定事件,点击发送消息
        send.addEventListener('click',()=>{
            let msg=message.value.trim()
            console.log(msg);
            if(msg.length<1 || msg.length>25) return
            //向服务端发送消息
            socket.emit('news',{msg,name,avatar})
            //输入完毕就清空
            message.value=''
        })

        //客户端接收服务端发来的count人数变化
        socket.on('countmsg',(data)=>{
            console.log(data);
            userNumber.innerHTML=data
        })


        //看是否点击登录,没有就跳转到登陆页面
        //获取查询字符串
        let search=decodeURI(location.search)
        console.log(search);
        if(!search){
            location.href='login.html'
        }
        
        //截取查询字符串的用户名与头像
        let name=search.split('&')[0].split('=')[1]
        let avatar=search.split('&')[1].split('=')[1]
        console.log(name,avatar);

        //登录成功后,更新界面中的头像和昵称
        userinfo.innerHTML=`<img src="images/avatar/${avatar}" alt="">              
                ${name}`
    </script>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./styles/chart.css">
    <link rel="stylesheet" href="./styles/normalize.css">
    <link rel="stylesheet" href="./styles/reset.css">
</head>
<body>
    <div id="login-container">
        <div class="login-title">微信聊天室</div>
        <div class="login-user-icon">
            <img src="images/login.png" alt="">
        </div>
        <div>
            <input type="text" id="username" class="login-item login-username" placeholder="请输入聊天昵称">
        </div>
        <div>
            <input type="button" id="login" class="login-item login-button" value="登录">
        </div>
    </div>
</body>
<script>
    login.addEventListener('click',()=>{
        //获取昵称
        let name=username.value
        console.log(name);
        //获取头像
        let avatar=Math.floor(Math.random()*100)+'.jpg'
        //点击登录跳转到index页面
        location.href=`index.html?name=${name}&avatar=${avatar}`
    })
</script>
</html>
app.js
const { Socket } = require('socket.io');

//引入express模块
const express=require('express')
const app=express()
//引入http模块
const server=require('http').Server(app)
//引入socket.io模块
const io=require('socket.io')(server)

//创建端口
server.listen(3000,()=>{
    console.log('server is Running');
})

//将静态资源托管到public目前下
app.use(express.static('./public'))

//声明一个变量。保存在线人数
let count=0
//建立连接
io.on('connection',(socket)=>{
    console.log('有人进来了',socket.id);
    //有人进来了,让count++
    count++
    //服务端将count实时发送给所有的客户端
    io.emit('countmsg',count)

    //当服务端发现有人离开就断开连接,count--
    socket.on('disconnect',()=>{
        count--
        io.emit('countmsg',count)
        console.log('有人离开了');
    })

    //通过socket监听获取文本
    socket.on('news',(data)=>{
        console.log(`${socket.id} 说:${data}`);
        console.log(data);
        //服务端接收消息把消息分发给客户端:广播
        io.emit('news',data)
    })
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值