欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于Socket.io的简易聊天室

程序员文章站 2022-07-10 21:21:01
...

基于Socket.io的简易聊天室

该聊天室样式写的很简易,甚至可以说low,但是咱们是研究技术的,样式不是重点 -。-

功能

  • 在线人员
  • 登录与退出
  • 当前用户
  • 实时发送消息
    基于Socket.io的简易聊天室基于Socket.io的简易聊天室
步骤一:首先要有个HTML页面才能展示这些内容吧,我这个聊天室使用的Vue的语法功能搭建的HTML,都是在一个HTML中写的,没有搭建成单页面应用。首先简易的把样式写了,能让我们看到这个效果就行(这里就不给大家写了,我相信大家都是会的,就不献丑了
步骤二:接下来才是进入正题了
  1. 先,初始化整个项目:cnpm init 在初始化的时候,记得指定入口文件为index.js, 这是我们服务端的入口文件 初始化完成后,代码中会多个package.json包

    -基于Socket.io的简易聊天室基于Socket.io的简易聊天室

  2. 二步,我们要创建这个Index.js,用来写我们的Node服务端代码,写代码之前,我们要先安装需要的依赖插件:expresssocket.io
    cnpm install express socket.io --save
    依赖安装完毕后,可以正式的撸码了!!!

    我们先将需要用到的模块包引入进来

    const express = require('express');
    const app = express();                              // 初始化express
    const http = require('http').Server(app);           // 创建个Http服务器
    const io = require('socket.io')(http);              // 将Http服务注入到io中
    const path = require('path');                       // 做路径处理
    

    首先我们先检验一下这个HTTP服务是否开启成功

    http.listen(3000, function(){
        console.log('服务开启成功')
    })
    

    利用nodemon 来运行该index.js
    基于Socket.io的简易聊天室
    验证成功,服务成功开启!

    接下来我们再来验证一下前端是否能够访问,这里利用express中的get方法来访问 ‘/’ 也就是根目录,调用send方法,向前端发送数据!

    app.get('/', function(req, res){
        res.send('Hello World')
    })
    

    打开浏览器输入我们监听的端口号:localhost:3000
    基于Socket.io的简易聊天室
    成功!
    现在前端与后端已经成功打通,接下来就是如何让页面显示我们想要显示的样子了

  3. 三步,将我们之前写好的前台HTML页面显示到浏览器中

    首先要使用express中的use方法,来指定静态资源目录,这样前端访问服务端的时候才能跳转到指定目录下(由于我的前台页面放到了public目录下,所以路径为 /public

    不懂path.join()方法?点我去看

    app.use(express.static(path.join(__dirname+ '/public')))            // app使用express的一个方法指定静态资源路径为public
    

    指定完成后,我们来修改一下之前写好的那个get方法,在之前,我们是向前台发送了一个Hello World字符串, 现在我们向前台发送整个HTML文件,利用sendFile()方法发送文件

    app.get('/', function(req, res){
        res.sendFile(path.join(__dirname+ '/public/index.html'))           // 将该路径发送到请求的地址中
    })
    

    将该页面发送到前台后,再次打开localhost:3000,就可以看到你之前写好的HTML页面了。

  4. 第4步,我们来写一下前台的HTML逻辑

    打开HTML, 首页肯定是要有一个输入框,一个登录按钮。由于我们使用的是Vue语法,所以我们要进行双向绑定一下这个输入框的值,在data中创建相对应的值
    基于Socket.io的简易聊天室
    logBol:是我们用来判断是否登录了,用来显示和隐藏登录页面的值
    user则是用户登录时存储的数据,其中uId为用户登录成功后,我们为用户随机生成的一个用户ID,这些创建完毕后,我们就开始写登录事件
    基于Socket.io的简易聊天室
    首先要判断需要输入有效值,再随机生成userId,生成ID之后,就可以调用initSocket初始化方法。

    //  生成用户Id
      genUid(){
          // 时间戳 + 随机数
          return `fc_${new Date().getTime() + ''}${Math.floor(Math.random()*89900)}`
      }
    

在初始化函数initSocket中,首先要建立socket的链接,随后可以向后台发送login登录事件,同时将当前用户登录的信息传递给后台
基于Socket.io的简易聊天室
接下来就是后台要监听前台发送来的事件,在index.js中建立监听
基于Socket.io的简易聊天室
当前台点击了登录之后,后台就可以监听到这个登录了,同时能够拿到前台发来的用户数据,res则为前台传来的用户数据,接收到后,我们可以将数据保存在后台,同时增加用户登录的在线数量, 同时利用emit事件再向前台广播(发送事件),告诉前台当前登录的游湖有哪些,以及用户数量,同时将传递进来的当前登录用户也返回回去
基于Socket.io的简易聊天室
基于Socket.io的简易聊天室
再接着就是前台监听后台发来的当前用户数据以及登录用户的总数据和总数量

// 接收到后台发来的在线用户,人数, 以及当前用户
this.Socket.on('login', res=>{
       this.proccessPlatform('login', res)
   });
proccessPlatform(state, res){
   // 将传来的对象转换为数组
   const arr = [];
   for(let [k, v] of Object.entries(res.onlineUsers)){
       arr.push({
           uid:k,
           username:v
       })
   }
   this.platform.userList = arr;
   this.platform.count = res.onlineCount;
   this.logBol = false
   this.message = `${res.user.userName}${state === 'login' ? '登录' : '离开了'}聊天室!`
},

接收到传来的值后,调用前台处理方法,用来存储传来的总用户数,以及数量。
platform为前台为了存储用户列表的对象
userList为用户数据列表
count:为总数量
message:为广播消息的值
将这些值都存储后,我们就可以将用户数据列表在HTML页面循环出来,同时还有数量总数。
到目前为止,我们的登录操作就已经完成了,接下来做的就是退出操作了,而退出操作是和登录几乎相同的,首先我们来看前台退出的事件
基于Socket.io的简易聊天室
前台关闭了socket后,后台index.js可以监听到关闭的事件

注意这个事件是写在io.on()的方法中,和之前监听用户登录方法并列

基于Socket.io的简易聊天室
首先要组成一个新的用户数据,用来告诉前端当前还有哪些用户在线已经总的数量
同时向前台发送logout事件,用来广播最新的用户数据列表、用户总量、哪位用户退出了

前台监听后台发送来的logout事件,监听到后,调用之前写好的proccessPlatform方法

// 退出事件发送过来后,当前用户是接收不到这个事件中的数据的
    this.Socket.on('logout', res=>{
          this.proccessPlatform('logout', res)
      })

目前为止,已经完成了用户登录以及用户退出的的方法,前台也可以接收到后台发送来的事件进行广播。

  1. 最后就是要做的用户聊天发送消息的处理
    首先是前台点击发送后,触发的发送事件
// 给后台发送用户输入消息
 send(){
      const req = {
          ...this.user,                   //当前用户发送
          content:this.content,           // 输入框中的值
      }
      this.Socket.emit('message', req)            // 告诉后台用户发送了消息
      // 我自己发的消息先行存在本地
      this.msgList.push({
          ...req,
          isMe:true                       // 判断是不是我发送的消息
      })
      // console.log(this.msgList)
      this.content = ''                   // 发送成功后清空输入框中的值
  },

后台对前台发送的消息事件做处理,在这里我们使用的和之前处理方法不一样,因为是发送消息,所以肯定会有是不是我发送的消息之分,所以使用的另外一个发送API,这样当前用户发送消息后,就不会向前台广播,而我们只需要在前台先行将我们发送的消息存储到本地列表中,这也就是我们上面缩写的前台处理事件中的push方法

注意这个事件是写在io.on()的方法中,和之前监听用户登录方法并列

// 监听客户端发送过来的数据
socket.on('message', res=> {
    // 发送过来消息,进行广播
    // console.log(res);
    // io.emit('message', res)      // 废弃(能够向所有用户发送消息)
    socket.broadcast.emit('message', res);   // 只会向除了自己的其他用户发送消息
})

接下来就是前台监听后台发来的message事件,在处理完后,将数据存储到前台消息列表中

// 后台广播数据
 this.Socket.on('message', res=>{
       // 接收到的都是用户发来的消息,肯定不是自己的,所以每一个都要设置isMe为false
       res.isMe = false;
       this.msgList.push(res)
   })

msgList:前台的消息列表
将拿到的消息列表循环显示到页面中就可以了

目前为止,整个聊天室算是基本完成了。
项目源码地址:https://github.com/BedRockGx/Socket