聊天室入门实战(node,sockte.io实现)--第三章(在线成员列表及头像显示,单聊)

项目已经部署,请访问: "chat.mycollagelife.com"

这是整个实战系列的第三章,这三章关联性较大,建议先阅读第一 , 第二两章,本章实现了在线成员的动态显示,和头像的匹配,单聊的设置,以及消息的美化,该系列教程非常详细,建议耐心读完。

实现的结果如图:

登录:



群聊,用户列表


单聊:

该项目已经上传至github  https://github.com/neuqzxy/chat  ,觉的可以的话,给个星星吧吐舌头

技术要求:

本章没有使用到什么其他的技术,如果你符合第二章的要求,就可以完成本章内容


实现在线用户列表


准备工作

1. 先拷贝一份第二章的源码到chat++文件夹中。

2. 逻辑分析:

在线用户列表是通过服务器端的全部成员数组来实现的,

首先,我们在登录之后要初始化用户列表,这需要服务器端返回一个数组,最少包括用户名和头像信息。

之后,处于登录状态,每次新增成员只需要服务器端广播该成员用户名和头像即可。

3. 界面调整:

我们要将界面分为两部分左部为用户列表,右部为聊天界面,并且聊天区域要设置最大的高度,超出显示滚动条。

创建静态文件

首先,用bootstrap的样式,将页面分成两部分,现在的所有内容为一部分,用户列表为另一部分,设置用户列表id为usergroup

<div style="display: none;" id="chatbox">
    <div id="usergroup" class="col-md-2">
        
    </div>
    <div class="col-md-9 col-md-offset-1">
        <div class="alert alert-info alert-dismissible fade in" role="alert" id="myalert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
        </div>
        <div class="alert alert-info alert-dismissible fade in" role="alert" id="myalert1">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
            <span></span>
        </div>
        <div id="content"></div>
        <div id="inputgrop">
            <div class="col-md-10">
                <input type="text" placeholder="saying somgthing" class="form-control chatinput" id="chatinput">
            </div>
            <form action="" style="display: none;" id="resetform"><input type="file" style="display: none" id="imginput"></form>
            <div class="col-md-2">
                <button type="button" class="btn btn-primary" id="imgbutton">发送图片</button>
            </div>
        </div>
    </div>
</div>

接下来我们使用bootstrap中的标签,显示在线成员字样,然后下面就是成员列表了:



<span  class="label label-primary" style="font-size: 2em;">在线成员</span>

成员列表我们使用bootstrap中的列表组来实现



    <div id="usergroup" class="col-md-2">
        <span  class="label label-primary" style="font-size: 2em;">在线成员</span>
        <div class="list-group"></div>
    </div>

现在看一下,已经成型了,但是聊天输入框的定位失效了,接下来我们打开开发者工具,发现html,chatbox 和里面两个div的高度全变成失效了,我们设置以下属性:

html,body {
            background: #ccc;
            padding: 20px 0 20px 0;
            height: 100%;
        }
#chatbox {
            height: 100%;
        }
然后再聊天区域的div里设置一个class,设置高度100%。

 <div class="col-md-9 chatwindow col-md-offset-1">

.chatwindow {
            height: 100%;
        }
现在就可以啦。

初始化页面时显示用户列表

当我们登录进去的时候要渲染出现在在线的所有用户,并且让自己排在第一位。

我们打开app.js在loginSuccess中添加一行,将所有用户数组传过去

            //然后触发loginSuccess事件告诉浏览器登陆成功了,广播形式触发
            data.userGroup = users;         //将所有用户数组传过去
            io.emit('loginSuccess',data);   //将data原封不动的再发给该浏览器

在main.js中,参照bootstrap的链接样式:

<div class="list-group">
  <a href="#" class="list-group-item active">
    Cras justo odio
  </a>
  <a href="#" class="list-group-item">Dapibus ac facilisis in</a>
  <a href="#" class="list-group-item">Morbi leo risus</a>
  <a href="#" class="list-group-item">Porta ac consectetur ac</a>
  <a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
我们这么写:

        /**
         * 用户列表渲染
         * 先添加自己,在从data中找到别人添加进去
         */
        _$listGroup.append(`<a href="#" class="list-group-item">${_username}</a>`);
        //添加别人
        for(let _user of data.userGroup) {
            if (_user.username !== _username) {
                _$listGroup.append(`<a href="#" class="list-group-item">${_user.username}</a>`);
            }
        }

注意传入data。  这样就渲染出来了。


用户上下线时列表更新

这部分逻辑要重新写监听事件:

首先我们在loginSuccess中写上线时列表更新,加一行就行:

    socket.on('loginSuccess',(data)=>{
        /**
         * 如果服务器返回的用户名和刚刚发送的相同的话,就登录
         * 否则说明有地方出问题了,拒绝登录
         */
        if(data.username === _username) {
            beginChat(data);
        }else {
            $('#myalert1 span').html(`<span>您的好友<strong>${data.username}</strong>上线了!</span>`);
            setTimeout(function() {
                $("#myalert1").hide();
            }, 1000);
            $("#myalert1").show();
            //用户列表添加该用户
            _$listGroup.append(`<a href="#" class="list-group-item">${data.username}</a>`);
        }
    });

然后我们写用户离开的监听。

    //断开连接后做的事情
    socket.on('disconnect',()=>{          //注意,该事件不需要自定义触发器,系统会自动调用
        usersNum --;
        console.log(`当前有${usersNum}个用户连接上服务器了`);

        //触发用户离开的监听
        socket.broadcast.emit("oneLeave",{username: socket.username});

        //删除用户
        users.forEach(function (user,index) {
            if(user.username === socket.username) {
                users.splice(index,1);       //找到该用户,删除
            }
        })
    })
之所以用socket.broadcast.io是因为我们不需要离开的用户知道了。

在main.js中监听,这里我们有两种方式,第一种:用数组记录下用户的列表,删除该用户,使用数组重新渲染。第二种:提前在DOM中标记,找到所在元素,删除。

这里显然第二种方式更加适合。

我们找到刚才添加的那些用户的<a>标签,给他们添加name属性,值为用户名。

然后写:

    socket.on('oneLeave',(data)=>{
        //找到该用户并删除
        _$listGroup.find($(`a[name='${data.username}']`)).remove();
    });


用户下线提示,及功能封装

还记得我们的好友上线提醒吗?我们现在写下线提醒:

我们复制一个红色警告框,

        <div class="alert alert-danger alert-dismissible fade in" role="alert" id="myalert2">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
            <span></span>
        </div>

然后让他隐藏,在beginChat里写:

        $("#myalert2").hide();
到了这里我们直接写一个函数,将好友上下线的功能写进去:

    /**
     *
     * @param flag 为1代表好友上线,-1代表好友下线
     * @param data 存储用户信息
     */
    let comAndLeave = function (flag,data) {
        //上线显示警告框,用户列表添加一个
        if(flag === 1) {
            $('#myalert1 span').html(`<span>您的好友<strong>${data.username}</strong>上线了!</span>`);
            setTimeout(function() {
                $("#myalert1").hide();
            }, 1000);
            $("#myalert1").show();
            //用户列表添加该用户
            _$listGroup.append(`<a href="#" name="${data.username}" class="list-group-item">${data.username}</a>`);
        } else {
            //下线显示警告框,用户列表删除一个
            $('#myalert2 span').html(`<span>您的好友<strong>${data.username}</strong>下线了!</span>`);
            setTimeout(function() {
                $("#myalert2").hide();
            }, 1000);
            $("#myalert2").show();
            //找到该用户并删除
            _$listGroup.find($(`a[name='${data.username}']`)).remove();
        }
    };

函数内容很简单,全都是复制之前的代码,现在loginSuccess和onLeave都只需要调用一下该函数就行了

    socket.on('oneLeave',(data)=>{
        comAndLeave(-1,data);
    });

    socket.on('loginSuccess',(data)=>{
        /**
         * 如果服务器返回的用户名和刚刚发送的相同的话,就登录
         * 否则说明有地方出问题了,拒绝登录
         */
        if(data.username === _username) {
            beginChat(data);
        }else {
            comAndLeave(1,data);
        }
    });


设置用户头像

到了这一步还不够,我们想有一个头像,这个头像是随机分配,但是在所有用户界面看都是相同的,所以我们需要随机选一个图片并广播给所有人。

我们进入阿里的图标库,选你喜欢的图片吧,可以添加至项目中以外链的形式加入到源码中。我已经选好了:

最后一个是自己,每个人随机头像自己是看不到的,在自己的界面只能看到最后的那个人头。

具体用法官网很清楚,我使用的是Symbol,因为他支持彩色。

我们打开使用帮助:

设置URL,css:

    <script src="http://at.alicdn.com/t/font_o86wdrgtu766r.js"></script>
    <style>
        .icon {
            width: 1em; height: 1em;
            vertical-align: -0.15em;
            fill: currentColor;
            overflow: hidden;
        }
    </style>
注意,每个人的URL不同。

在showMessage,showImg,beginChat等地方设置本人头像:

/**
 * Created by zhouxinyu on 2017/8/6.
 */
$(function(){
    const url = 'http://127.0.0.1:3000';
    let _username = null;
    let _$inputname = $("#name");
    let _$loginButton = $("#loginbutton");
    let _$chatinput = $("#chatinput");
    let _$inputGroup = $("#inputgrop");
    let _$imgButton = $("#imgbutton");
    let _$imgInput = $("#imginput");
    let _$listGroup = $(".list-group");

    let socket = io.connect(url);

    //设置用户名,当用户登录的时候触发
    let setUsername = function () {
        _username = _$inputname.val().trim();    //得到输入框中用户输入的用户名

        //判断用户名是否存在
        if(_username) {
            soc
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现一个基于 Node.jssocket.io 的多人聊天室,您需要遵循以下步骤: 1. 安装 Node.jssocket.io 2. 创建一个新的 Node.js 项目 3. 在项目根目录下创建一个名为 index.js 的文件 4. 在 index.js 中引入 socket.io 模块: ```javascript const io = require('socket.io')(server); ``` 5. 创建一个 HTTP 服务器对象: ```javascript const server = require('http').createServer(); ``` 6. 监听 HTTP 服务器对象: ```javascript server.listen(3000, () => { console.log('Server listening on port 3000'); }); ``` 7. 在客户端页面上引入 socket.io.js: ```html <script src="/socket.io/socket.io.js"></script> ``` 8. 在客户端代码中连接到服务器: ```javascript const socket = io.connect('http://localhost:3000'); ``` 9. 在服务器端监听客户端连接事件: ```javascript io.on('connection', (socket) => { console.log('Client connected'); }); ``` 10. 在服务器端监听客户端发送消息事件: ```javascript socket.on('message', (data) => { console.log(`Message received: ${data}`); }); ``` 11. 在客户端发送消息到服务器: ```javascript socket.emit('message', 'Hello, server'); ``` 12. 实现聊天室在线人数与名称显示功能: ```javascript io.on('connection', (socket) => { console.log('Client connected'); // 发送在线人数和名称 io.emit('online', { count: io.engine.clientsCount, names: Object.keys(io.sockets.sockets).map((id) => io.sockets.sockets[id].username), }); }); ``` 13. 实现客户端登入登出提醒功能: ```javascript io.on('connection', (socket) => { console.log('Client connected'); // 发送登入提醒 socket.broadcast.emit('login', { username: socket.username, }); // 发送在线人数和名称 io.emit('online', { count: io.engine.clientsCount, names: Object.keys(io.sockets.sockets).map((id) => io.sockets.sockets[id].username), }); // 监听登出事件 socket.on('disconnect', () => { console.log('Client disconnected'); // 发送登出提醒 socket.broadcast.emit('logout', { username: socket.username, }); // 发送在线人数和名称 io.emit('online', { count: io.engine.clientsCount, names: Object.keys(io.sockets.sockets).map((id) => io.sockets.sockets[id].username), }); }); }); ``` 以上就是基于 Node.jssocket.io 实现多人聊天室的主要步骤和代码实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值