最近因为要做一个实时传输视频的设备,前端用Vue写的,后端用egg写的。所以,准备使用egg-socket来配置文档。
1.egg中首先按照egg-socket包
npm i --save egg-socket
2.配置socket,在config文件夹中,先在plugin.js中配置包依赖
io: {
enable: true,
package: ‘egg-socket.io’,
},
接着打开config.default.js配置
config.io = {
namespace: {
‘/’: {
//配置中间件接收处理
connectionMiddleware: [ ‘auth’ ],
//处理回来的数据
packetMiddleware: [ ‘filter’ ],
},
},
//这一步可以不要。如果后面要指定客户端的发送的话,这一步不要写。
generateId: req => { //自定义 socket.id 生成函数
const data = qs.parse(req.url.split(’?’)[1]);
return data; // custom id must be unique
},
};
在app下,我们要创建io文件。创建controller文件夹,middleware文件夹。
接下来要在middleware中配置好上面定义的俩个字段的文件夹。
auth.js
/*
* @Description:
* @Author: msq
* @Date: 2021-06-01 09:06:43
* @LastEditTime: 2021-06-01 22:27:03
* @LastEditors: msq
* @Reference:
*/
'use strict';
const fs = require('fs')
const path = require('path')
// 这个中间件的作用是提示用户连接与断开的,连接成功的消息发送到客户端,断开连接的消息在服务端打印
module.exports = app => {
let room =[]
return function* (next) {
this.socket.join('all')
let id = String(this.request.header.referer).split('=')[1]
console.log(room.length)
if(room.length>0){
console.log('hahahahah')
let flag = false
flag = room.some(v=>{
return Number(v.id) === Number(id)
})
if(!flag){
room.push({id,query:this.socket.id})
}
}else{
console.log('sdasdsa')
room.push({id,query:this.socket.id})
}
// console.log(parm)
console.log(room)
let file = path.resolve(__dirname, '../../public/s.json')
fs.appendFile(file,JSON.stringify({id,query:this.socket.id})+'\n', "utf-8", function ( err ) {
if( err ){
console.log( "数据追加失败" );
}else{
console.log( "数据追加成功" );
}
} )
// console.log('chat 控制器打印', message);
yield* next;
console.log('disconnection!');
console.log('asdasds')
};
};
filter.js
'use strict';
// 这个中间件的作用是将接收到的数据再发送给客户端
module.exports = app => {
return function*(next) {
// this.socket.emit('res', 'packet received!');
// console.log('packet:', this.packet);
yield* next;
};
};
接下来我们可以在controller中写我们的程序.
/*
* @Description:
* @Author: msq
* @Date: 2021-06-01 09:06:43
* @LastEditTime: 2021-06-01 22:23:50
* @LastEditors: msq
* @Reference:
*/
'use strict';
const fs = require('fs')
const path = require('path')
// 将收到的消息发送给客户端
module.exports = app => {
let room = []
class Controller extends app.Controller {
async index() {
const {socket,app, query} = this.ctx
let file = path.resolve(__dirname, '../../public/s.json')
// fs.readFile(file, "utf-8", function(error, data) {
// console.log(data)
// console.log(typeof data)
// // let da = JSON.parse(data)
// // console.log(error); //如果err为null就说明读取成功了,没有出错
// // console.log(data); // 如果不给第二个参数[读取的文件编码格式]就会以beffer格式输出
// // const d = da.find((v)=>{
// // return Number(v.id) === 7
// // })
// // console.log(d)
// // const nsp = app.io.of('/');
// // nsp.sockets[JSON.parse(data)].emit('res', "hello ");
// // 用error来判断文件是否读取成功
// if (error) return console.log("读取文件失败,内容是" + error.message);
// // console.log("读取文件成功,内容是" + JSON.parse(data));
// });
fs.readFile(file, "utf-8", function(error, data) {
console.log(data.split('\n'))
console.log(typeof data)
let s = []
let x = data.split('\n')
x.forEach(v=>{
if(v != ''){
s.push(JSON.parse(v))
}
})
console.log(s)
const nsp = app.io.of('/');
// console.log(s[0].query)
**// console.log(nsp.sockets)**
// console.log('------------')
// console.log(socket.id)
// console.log(nsp.sockets)
// console.log(nsp.sockets[{"EIO":"3","transport":"polling","t":"Nd7gTle"}])
// console.log('-----------------')
console.log('-----------[')
console.log('-------------')
console.log(**nsp.sockets[s[0].query]**)
// console.log(socket)
socket.to(s[0].query).emit('res','hello')
// socket[s[0].query].emit('res', "hello ");
// if (error) return console.log("读取文件失败,内容是" + error.message);
// console.log("读取文件成功,内容是" + JSON.parse(data));
});
// const id = this.ctx.config.generateId()
// console.log(id)
}
}
return Controller;
};
nsp.sockets中包含了所有 的客户端连接。如果要指定客户端可以利用 socket.id拿取,然后取到客户端连接。
Vue前端
在Vue中配置的话主要是下载 vue-socket.io和socket.io-client俩个包
首先在main.js中配置
import VueSocketio from 'vue-socket.io';
import socketio from 'socket.io-client';
Vue.use(VueSocketio, socketio(**'http://10.248.124.212:7001**'));
//这里是上面egg项目的后端地址。
接下来我们就可以在页面中使用了。
在页面的中,
sockets: {}
跟methods是同级别的。道理是一样的噢。
如果有小伙棒需要源码,可以@我。