From c927b5ae244478b88bd3026f94dddc2e21adaaa8 Mon Sep 17 00:00:00 2001 From: Imfdj <907765782@qq.com> Date: Wed, 19 May 2021 16:46:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7room=EF=BC=8C=E6=8F=90=E4=BE=9Bonline=E3=80=81join?= =?UTF-8?q?=E3=80=81leave=E5=90=8C=E6=AD=A5socket=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加线用户room,提供online、join、leave同步socket指令; --- app/extend/helper.js | 21 +++++++++++++++++++++ app/io/middleware/connection.js | 33 +++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/extend/helper.js b/app/extend/helper.js index fb174e3..252a2ef 100644 --- a/app/extend/helper.js +++ b/app/extend/helper.js @@ -40,6 +40,27 @@ module.exports = { app.logger.errorAndSentry(e); } }, + /** + * 发送socket消息给在线room里的每个连接,并录入redis + */ + sendSocketToOnlineOfRoom(params, action, roomName, messageType = 'sync', method = 'publish') { + const { ctx, app, redisKeys } = this; + const nsp = app.io.of('/'); + try { + nsp.adapter.clients([roomName], (err, clients) => { + clients.forEach(clientId => { + const data = ctx.helper.parseSocketMsg(params, clientId, action, method); + const socket = nsp.to(clientId); + const emitData = [messageType, data]; + socket.emit(...emitData); + // 存入redis,接收到ACK则删除,否则在 this.app.config.socketRedisExp 时间内多次重发 + app.redis.setex(redisKeys.socketBaseSocketId(data.id), app.config.socketRedisExp, JSON.stringify(emitData)); + }); + }); + } catch (e) { + app.logger.errorAndSentry(e); + } + }, /** * 给单个socket发送消息,并录入redis */ diff --git a/app/io/middleware/connection.js b/app/io/middleware/connection.js index c84e17b..6525813 100644 --- a/app/io/middleware/connection.js +++ b/app/io/middleware/connection.js @@ -3,6 +3,7 @@ module.exports = app => { return async (ctx, next) => { const { socket, logger } = ctx; + const { socketOnlineUserRoomName } = app.config; const nsp = app.io.of('/'); console.log('start connection!'); console.log('allSockets'); @@ -18,7 +19,27 @@ module.exports = app => { socket.disconnect(); } await app.jwt.verify(token, app.config.jwt.secret); - + // 加入在线用户room + socket.join(socketOnlineUserRoomName, () => { + setTimeout(() => { + // 给已在线用户发送join + // nsp.to(socketOnlineUserRoomName) + // .emit('join', socket.id); + ctx.helper.sendSocketToOnlineOfRoom({ socketId: socket.id }, 'join', socketOnlineUserRoomName); + nsp.adapter.clients([socketOnlineUserRoomName], (err, clients) => { + if (err) logger.error(err); + const ids = new Set(clients); + ids.add(socket.id); + // 发送当前在线用户ids + const _message = ctx.helper.parseSocketMsg(Array.from(ids), socket.id, 'online'); + const emitData = ['sync', _message]; + socket.emit(...emitData); + // 存入redis,接收到ACK则删除,否则在 this.app.config.socketRedisExp 时间内多次重发 + app.redis.setex(ctx.helper.redisKeys.socketBaseSocketId(_message.id), app.config.socketRedisExp, JSON.stringify(emitData)); + // socket.emit('online', Array.from(ids)); + }); + }); + }); // 获取用户参与的项目,根据项目ID创建room const userProjects = await ctx.model.UserProjects.findAll({ where: { user_id: userId }, @@ -52,8 +73,12 @@ module.exports = app => { await next(); console.log('disconnect!'); console.log(socket.id); - // nsp.adapter.rooms.forEach(room => { - // socket.leave(room); - // }); + socket.join(socketOnlineUserRoomName, () => { + setTimeout(() => { + ctx.helper.sendSocketToOnlineOfRoom({ socketId: socket.id }, 'leave', socketOnlineUserRoomName); + // nsp.to(socketOnlineUserRoomName) + // .emit('leave', socket.id); + }); + }); }; };