0

0

如何实现node+express个性化聊天室?

亚连

亚连

发布时间:2018-06-07 16:12:17

|

1653人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了零基础实现node+express个性化聊天室的示例,现在分享给大家,也给大家做个参考。

本篇文章使用node+express+jquery写一个个性化聊天室,一起来get一下~(源码地址见文章末尾)

效果图

项目结构

实现功能

  1. 登录检测

  2. 系统自动提示用户状态(进入/离开)

  3. 显示在线用户

  4. 支持发送和接收消息

  5. 自定义字体颜色

  6. 支持发送表情

  7. 支持发送图片

下面将一一讲解如何实现

前期准备

node及npm环境、express、socket.io

具体实现

1、将聊天室部署到服务器

先用node搭建一个服务器,部署在localhost:3000端口,先尝试向浏览器发送一个“hello world”,新建server.js文件。

var app = require('express')(); // 引入express模块
var http = require('http').Server(app);

app.get('/', function(req, res){ // 路由为localhost:3000时向客户端响应“hello world”
 res.send('

Hello world

'); // 发送数据 }); http.listen(3000, function(){ // 监听3000端口 console.log('listening on *:3000'); });

打开浏览器输入网址:localhost:3000是这样的

一个node服务器搭建成功。

接下来用express向浏览器返回一个html页面

#安装express模块
npm install --save express

将server.js的代码改一下:

var express = require('express');
var app = express();
var http = require('http').Server(app); 

// 路由为/默认www静态文件夹
app.use('/', express.static(__dirname + '/www'));

express.static(__dirname + '/www');是将www文件夹托管为静态资源,意味着这个文件夹里的文件(html、css、js)彼此可以用相对路径。在www文件夹中添加index.html文件以及相应的css(相应css代码就不贴了,详情见源码),如下,该页面用了font-awesome小图标



   
 
 
 chat
 
 
 
 
 

@@##@@ happy聊天室

    在线人员(0)

      当前无人在线哟~

      打开localhost:3000,会看到如下:

      如何实现node+express个性化聊天室?

      聊天室成功部署到服务器。

      2、检测登录

      在客户端和服务器之间传送消息需要用到socket.io

      #安装socket.io模块
      npm install --save socket.io

      将server.js改动如下:

      var app = require('express')();
      var http = require('http').Server(app);
      var io = require('socket.io')(http);
      
      app.use('/', express.static(__dirname + '/www'));
      
      io.on('connection', function(socket){ // 用户连接时触发
       console.log('a user connected');
      });
      
      http.listen(3000, function(){
       console.log('listening on *:3000');
      });

      当打开localhost:3000的时候会触发服务器端io的connection事件,会在服务器打印“a user connected”,但是我们想统计一下连接该服务器的用户人数,如果有用户连接就打印“n users connected”,n为用户人数,怎么办呢?

      在server.js设置一个全局数组为user,每当一个用户连接成功就在连接事件中将用户的昵称push进user,打印user.length即可知道已成功连接用户的人数。

      等一等。

      在用户连接的时输入昵称登录,我们应该检测一下用户的昵称是否已存在,避免昵称相同的情况发生,在服务器监听一个登录事件来判断该情况,由于一切都发生在用户连接之后,所以触发事件应该写在connection事件的回调函数中。

      io.on('connection', (socket)=> {
       // 渲染在线人员
       io.emit('disUser', usersInfo);
      
       // 登录,检测用户名
       socket.on('login', (user)=> {
        if(users.indexOf(user.name) > -1) { // 昵称是否存在
         socket.emit('loginError'); // 触发客户端的登录失败事件
        } else {
         users.push(user.name); //储存用户的昵称
         usersInfo.push(user); // 储存用户的昵称和头像
         socket.emit('loginSuc'); // 触发客户端的登录成功事件
         socket.nickname = user.name;
         io.emit('system', { // 向所有用户广播该用户进入房间
          name: user.name,
          status: '进入'
         });
         io.emit('disUser', usersInfo); // 渲染右侧在线人员信息
         console.log(users.length + ' user connect.'); // 打印连接人数
        }
       });

      system和disUser事件先不管,之后再说 区分io.emit(foo)、socket.emit(foo)、socket.broadcast.emit(foo)

      io.emit(foo); //会触发所有客户端用户的foo事件
      socket.emit(foo); //只触发当前客户端用户的foo事件
      socket.broadcast.emit(foo); //触发除了当前客户端用户的其他用户的foo事件

      接下来是客户端代码chat-client.js

      $(function() {
        // io-client
        // 连接成功会触发服务器端的connection事件
        var socket = io();
      
        // 点击输入昵称
        $('#nameBtn').click(()=> { 
         var imgN = Math.floor(Math.random()*4)+1; // 随机分配头像
         if($('#name').val().trim()!=='')
           socket.emit('login', { // 触发服务器端登录事件
            name: $('#name').val(),
            img: 'image/user' + imgN + '.jpg'
           }); 
         return false; 
        });
        // 登录成功,隐藏登录层
        socket.on('loginSuc', ()=> { 
         $('.name').hide(); 
        })
        socket.on('loginError', ()=> {
         alert('用户名已存在,请重新输入!');
         $('#name').val('');
        }); 
      });

      倘若登录成功,会看到如下页面:

      Bika.ai
      Bika.ai

      打造您的AI智能体员工团队

      下载

      登录检测完成。

      3、系统自动提示用户状态(进入/离开)

      该功能是为了实现上图所示的系统提示“XXX进入聊天室”,在登录成功时触发system事件,向所有用户广播信息,注意此时用的是io.emit而不是socket.emit,客户端代码如下

      // 系统提示消息
      socket.on('system', (user)=> { 
       var data = new Date().toTimeString().substr(0, 8);
       $('#messages').append(`

      ${data}
      ${user.name} ${user.status}了聊天室

      `); // 滚动条总是在最底部 $('#messages').scrollTop($('#messages')[0].scrollHeight); });

      4、显示在线用户

      客户端监听一个显示在线用户的事件disUser,在以下三个时间段服务器端就触发一次该事件重新渲染一次

      1. 程序开始启动时

      2. 每当用户进入房间

      3. 每当用户离开房间

      // chat-client.js
      // 显示在线人员
      socket.on('disUser', (usersInfo)=> {
       displayUser(usersInfo);
      });
      // 显示在线人员
      function displayUser(users) {
       $('#users').text(''); // 每次都要重新渲染
       if(!users.length) {
        $('.contacts p').show();
       } else {
        $('.contacts p').hide();
       }
       $('#num').text(users.length);
       for(var i = 0; i < users.length; i++) {
        var $html = `
    • @@##@@ ${users[i].name}
    • `; $('#users').append($html); } }

      5、支持发送和接收消息

      用户发送消息时触发服务器端的sendMsg事件,并将消息内容作为参数,服务器端监听到sendMsg事件之后向其他所有用户广播该消息,用的socket.broadcast.emit(foo)

       // server.js
        // 发送消息事件
        socket.on('sendMsg', (data)=> {
          var img = '';
          for(var i = 0; i < usersInfo.length; i++) {
            if(usersInfo[i].name == socket.nickname) {
              img = usersInfo[i].img;
            }
          }
          socket.broadcast.emit('receiveMsg', { // 向除了发送者之外的其他用户广播
            name: socket.nickname,
            img: img,
            msg: data.msg,
            color: data.color,
            side: 'left'
          });
          socket.emit('receiveMsg', { // 向发送者发送消息,为什么分开发送?因为css样式不同
            name: socket.nickname,
            img: img,
            msg: data.msg,
            color: data.color,
            side: 'right'
          });
        });

      服务器端接受到来自用户的消息后会触发客户端的receiveMsg事件,并将用户发送的消息作为参数传递,该事件会向聊天面板添加聊天内容,以下为chat-client.js代码

      // 点击按钮或回车键发送消息
        $('#sub').click(sendMsg);
        $('#m').keyup((ev)=> {
         if(ev.which == 13) {
          sendMsg();
         }
        });
      
        // 接收消息
        socket.on('receiveMsg', (obj)=> { // 将接收到的消息渲染到面板上
         $('#messages').append(` 
           
    • @@##@@

      ${obj.name}

      ${obj.msg}

    • `); // 滚动条总是在最底部 $('#messages').scrollTop($('#messages')[0].scrollHeight); }); // 发送消息 function sendMsg() { if($('#m').val() == '') { // 输入消息为空 alert('请输入内容!'); return false; } socket.emit('sendMsg', { msg: $('#m').val() }); $('#m').val(''); return false; }

      6、自定义字体颜色

      得益于html5的input新特性,可以通过type为color的input调用系统调色板

      
      

      客户端根据用户选择的颜色渲染内容样式,代码很容易看懂,这里就不赘述了。

      7、支持发送表情

      发送表情其实很简单,将表情图片放在li中,当用户点击li时就将表情的src中的序号解析出来,用[emoji+表情序号]的格式存放在聊天框里,点击发送后再解析为src。就是一个解析加还原的过程,这一过程中我们的服务器代码不变,需要改变的是客户端监听的receiveMsg事件。

      // chat-client.js
      
        // 显示表情选择面板
        $('#smile').click(()=> {
         $('.selectBox').css('display', "block");
        });
        $('#smile').dblclick((ev)=> { 
         $('.selectBox').css('display', "none");
        }); 
        $('#m').click(()=> {
         $('.selectBox').css('display', "none");
        });
      
        // 用户点击发送表情
        $('.emoji li img').click((ev)=> {
          ev = ev || window.event;
          var src = ev.target.src;
          var emoji = src.replace(/\D*/g, '').substr(6, 8); // 提取序号
          var old = $('#m').val(); // 用户输入的其他内容
          $('#m').val(old+'[emoji'+emoji+']');
          $('.selectBox').css('display', "none");
        });

      客户端收到之后将表情序号还原为src,更改如下

      // chat-client.js
      
        // 接收消息
        socket.on('receiveMsg', (obj)=> { 
         // 提取文字中的表情加以渲染
         var msg = obj.msg;
         var content = '';
         while(msg.indexOf('[') > -1) { // 其实更建议用正则将[]中的内容提取出来
          var start = msg.indexOf('[');
          var end = msg.indexOf(']');
      
          content += ''+msg.substr(0, start)+'';
          content += '@@##@@';
          msg = msg.substr(end+1, msg.length);
         }
         content += ''+msg+'';
         
         $('#messages').append(`
          
    • @@##@@

      ${obj.name}

      ${content}

    • `); // 滚动条总是在最底部 $('#messages').scrollTop($('#messages')[0].scrollHeight); });

      可以成功发送表情了。

      8、支持发送图片

      首先是图片按钮样式,发送图片的按钮是type为file的input。这里有一个改变样式的小技巧,那就是将input的透明度设为0,z-index为5,将你想要得样式放在p中,z-index设为1覆盖在input上。

      
      
      css:
      
      .edit #file {
        width: 32.36px;
        height: 29px;
        opacity: 0;
        z-index: 5;
      }
      .edit #img {
        z-index: 0;
        margin-left: -43px;
      }

      完美

      如何实现node+express个性化聊天室?

      接下来是点击按钮发送图片,我们用了fileReader对象,这里有一篇不错的文章讲解了fileReader,fileReader是一个对象,可以将我们选中的文件已64位输出然后将结果存放在reader.result中,我们选中图片之后,reader.result就存放的是图片的src

      // chat-client.js
      
        // 用户发送图片
        $('#file').change(function() {
         var file = this.files[0]; // 上传单张图片
         var reader = new FileReader();
      
         //文件读取出错的时候触发
         reader.onerror = function(){
           console.log('读取文件失败,请重试!'); 
         };
         // 读取成功后
         reader.onload = function() {
          var src = reader.result; // 读取结果
          var img = '@@##@@';
          socket.emit('sendMsg', { // 发送
           msg: img,
           color: color,
           type: 'img' // 发送类型为img
          }); 
         };
         reader.readAsDataURL(file); // 读取为64位
        });

      由于发送的是图片,所以对页面布局难免有影响,为了页面美观客户端在接收其他用户发送的消息的时候会先判断发送的是文本还是图片,根据不同的结果展示不同布局。判断的方法是在客户发送消息的时候传入一个type,根据type的值来确实发送内容的类型。所以上面发送图片代码中触发了sendMsg事件,传入参数多了一个type属性。

      响应的,我们应该在chat-client.js中修改receiveMsg事件监听函数,改为根据传入type做不同操作

      chat-client.js
        // 接收消息
        socket.on('receiveMsg', (obj)=> { 
         // 发送为图片
         if(obj.type == 'img') {
          $('#messages').append(`
           
    • @@##@@

      ${obj.name}

      ${obj.msg}

    • `); $('#messages').scrollTop($('#messages')[0].scrollHeight); return; } // 提取文字中的表情加以渲染 // 下面不变 });

      现在我们可以发送图片了

      如何实现node+express个性化聊天室?

      上面是我整理给大家的,希望今后会对大家有帮助。

      相关文章:

      在vue中如何使用cli请求代理与项目打包方面的问题

      在vue-cli中使用webpack模板解决项目搭建及打包路径问题

      在vue中bus全局事件中心(详细教程)

      如何实现node+express个性化聊天室?如何实现node+express个性化聊天室?如何实现node+express个性化聊天室?如何实现node+express个性化聊天室?

      热门AI工具

      更多
      DeepSeek
      DeepSeek

      幻方量化公司旗下的开源大模型平台

      豆包大模型
      豆包大模型

      字节跳动自主研发的一系列大型语言模型

      通义千问
      通义千问

      阿里巴巴推出的全能AI助手

      腾讯元宝
      腾讯元宝

      腾讯混元平台推出的AI助手

      文心一言
      文心一言

      文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

      讯飞写作
      讯飞写作

      基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

      即梦AI
      即梦AI

      一站式AI创作平台,免费AI图片和视频生成。

      ChatGPT
      ChatGPT

      最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

      相关专题

      更多
      俄罗斯Yandex引擎入口
      俄罗斯Yandex引擎入口

      2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

      178

      2026.01.28

      包子漫画在线官方入口大全
      包子漫画在线官方入口大全

      本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

      35

      2026.01.28

      ao3中文版官网地址大全
      ao3中文版官网地址大全

      AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

      79

      2026.01.28

      php怎么写接口教程
      php怎么写接口教程

      本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

      2

      2026.01.28

      php中文乱码如何解决
      php中文乱码如何解决

      本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

      4

      2026.01.28

      Java 消息队列与异步架构实战
      Java 消息队列与异步架构实战

      本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

      8

      2026.01.28

      Python 自然语言处理(NLP)基础与实战
      Python 自然语言处理(NLP)基础与实战

      本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

      24

      2026.01.27

      拼多多赚钱的5种方法 拼多多赚钱的5种方法
      拼多多赚钱的5种方法 拼多多赚钱的5种方法

      在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

      122

      2026.01.26

      edge浏览器怎样设置主页 edge浏览器自定义设置教程
      edge浏览器怎样设置主页 edge浏览器自定义设置教程

      在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

      72

      2026.01.26

      热门下载

      更多
      网站特效
      /
      网站源码
      /
      网站素材
      /
      前端模板

      精品课程

      更多
      相关推荐
      /
      热门推荐
      /
      最新课程
      HTML5/CSS3/JavaScript/ES6入门课程
      HTML5/CSS3/JavaScript/ES6入门课程

      共102课时 | 6.8万人学习

      前端基础到实战(HTML5+CSS3+ES6+NPM)
      前端基础到实战(HTML5+CSS3+ES6+NPM)

      共162课时 | 19.1万人学习

      第二十二期_前端开发
      第二十二期_前端开发

      共119课时 | 12.6万人学习

      关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
      php中文网:公益在线php培训,帮助PHP学习者快速成长!
      关注服务号 技术交流群
      PHP中文网订阅号
      每天精选资源文章推送

      Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号