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就可以使用了
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、流程图
5、效果图
6、参考文献