socket.io实现多人聊天

1、 后端环境搭建

# npm init
# npm install -s express
# npm install -s socket.io 

npm init 会生成json文件作为依赖包,express和socket.io插件安装完成后会生成node_modules文件夹和package-lock.json锁依赖文件,该文件记录插件的版本。

完成以上步骤并创建index.js文件作为后端的入口文件。

2、 后端入口文件

1)在index,js内首先需要引入已经安装的插件

/* 引入插件 */
const express = require('express')
const socket = require('socket.io')
const app = express()

2)需要设置跨域访问

/* 设置跨域访问 */
app.all('*', function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("X-Powered-By", ' 3.2.1')
  res.header("Content-Type", "application/json;charset=utf-8");
  next();
});

3)监听端口号并响应前台请求

/* 监听端口号 */
const server = app.listen(4000,()=>{
  console.log('正在监听4000端口...')
})
/* 监听前端请求事件 */
const io = socket(server)
let num = 0 //在线总人数
io.on('connection',(socket) => {
    // 响应连接(响应体)
}

当前台使用io.connect()连接端口号的时候,后端就会监听到并响应。以下代码都在响应体内

4)响应体 -- 监听某某上线

let auther = null //上线人名称
num++
// 上线
socket.on('online',(name)=>{
  console.log(name+'上线 ')
  auther = name
  const obj = {
    num: num,
    name: name
  }
  io.sockets.emit('online',obj)
})

某某上线时,需要先将上线总人数加一,前台连接完成后马上就会向后台传递名称name给online事件,后台监听到online事件,记录上线人的名称,这里主要用于后面的离线。然后将某某上线的信息通过io.sockets广播给所有(包括自己)已经连接的页面。

5)响应体 -- 监听某某正在输入

// 监听正在输入...
socket.on('typing',(name) => {
  socket.broadcast.emit('typing',name)
});

当某某在input标签输入内容时,会将名称发给后台typing事件,后台监听typing并响应,通过socket.broadcast广播给所有页面(除了自己)

6)响应体 --  监听发言

// 接收发言并返回
  socket.on('chat',(data) => {
    io.sockets.emit('chat',data)
    console.log(data)
  });

 

某某在前台向后台chat事件发送信息(内容和名称),后台监听chat事件并响应,将信息广播给所有页面。

7)响应体 --  监听离线

// 监听离线...
  socket.on('disconnect',()=>{
    console.log(auther+'离线...')
    num--
    const obj = {
      num: num,
      name: auther
    }
    io.sockets.emit('offline',obj)
  });

前台离开页面时会触发disconnect事件,后台监听到disconnect事件并作出响应,将之前保存的名称和减一的在线总人数广播给所有页面。到这里,后端的所有逻辑就已经准备就绪,可以启动后端了.......

3、 前台请求体

本次前台页面使用vue编写,

1) 引入socket.io(在vue项目的根页面index.html内引入),引入之后io就可以使用了

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.dev.js"></script>

2) 在首页内需要先生成自己的名称(这里我随机生成名称 ),连接后台并把名称传给后台,告诉其他页面某某加入聊天了。这里我创建了一个类用于处理连接后台,该类一旦创建,constructor就会执行,因此就会连接后台并传递名称给后台,后台监听online并接受数据,然后广播给所有页面。

this.auther = '阿' + Math.floor(Math.random()*20)
this.chat = new Chat(this.auther)
//类chat内有connect方法
connect() {
 this.socket = io.connect('http://10.112.169.51:4000')
 this.socket.emit('online',this.name)
}

3) 接收某某上线,已经向后台触发online事件,这时需要接收后台广播的上线人数和某某上线

this.chat.socket.on('online',(obj)=>{
  this.title = `在线网友(${obj.num}人)`
  this.keypress = `${obj.name}加入聊天`
})

4) 接收正在输入,当input有值的时候需要传名称给后台,后台也会广播给所有页面,同时需要接收广播的数据

watch: {
  value() {
    this.chat.socket.emit('typing', this.value.trim() ? this.auther : '')
  }
},

this.chat.socket.on('typing',(data)=>{

  this.keypress = data ? data+'正在输入...' : ''

})

5) 接收发言,前台通过发送按钮将发言信息和名称传给后台,后台广播给所有页面,所有需要接收广播信息

this.chat.socket.on('chat',(data)=>{
   this.list.push({
     imgUrl: require('@/assets/styles/images/asan.jpg'),
     auther: data.name,
     content: data.value,
     self: data.name === this.auther
   })
   setTimeout(()=>{
     if(this.scroll.maxScrollY) this.scroll.scrollTo(0,this.scroll.maxScrollY)
   },100)
})

6) 离线处理,前台在离开页面的时候会告诉后台断开连接。到此,前台的主要逻辑也已经完成(由于只附上主要逻辑,具体代码可看我的github前台github后台),启动前台

disconnect() {
  this.socket.disconnect()
}

4、流程图

socket.io实现多人聊天

5、效果图

socket.io实现多人聊天

 

 6、参考文献

https://socket.io/docs/

https://hackernoon.com/an-overview-of-frontend-and-backend-interaction-48l031ba

上一篇:php-Facebook XMPP中发生错误


下一篇:android-如何在聊天应用上使用不同类型的消息来组织RecyclerView?