|
@@ -1,6 +1,7 @@
|
|
import { InjectRedis } from '@liaoliaots/nestjs-redis';
|
|
import { InjectRedis } from '@liaoliaots/nestjs-redis';
|
|
import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
|
import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
|
import { Redis } from 'ioredis';
|
|
import { Redis } from 'ioredis';
|
|
|
|
+import { Socket } from 'socket.io';
|
|
|
|
|
|
import { SocketGateway } from 'src/socket/socket.gateway';
|
|
import { SocketGateway } from 'src/socket/socket.gateway';
|
|
import { ActionsService } from './actions/actions.service';
|
|
import { ActionsService } from './actions/actions.service';
|
|
@@ -14,8 +15,9 @@ export class RoomService {
|
|
@InjectRedis() private readonly redis: Redis,
|
|
@InjectRedis() private readonly redis: Redis,
|
|
private readonly userService: UsersService,
|
|
private readonly userService: UsersService,
|
|
private readonly actionsService: ActionsService,
|
|
private readonly actionsService: ActionsService,
|
|
- ) {}
|
|
|
|
|
|
+ ) { }
|
|
public readonly logger = new Logger('user');
|
|
public readonly logger = new Logger('user');
|
|
|
|
+ public _sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
|
public _userInfo = {} as UserInfoType;
|
|
public _userInfo = {} as UserInfoType;
|
|
private _roomConfig = {} as RoomConfigType;
|
|
private _roomConfig = {} as RoomConfigType;
|
|
private isJoin = false;
|
|
private isJoin = false;
|
|
@@ -35,13 +37,14 @@ export class RoomService {
|
|
*/
|
|
*/
|
|
initUserProfile(userInfo: UserInfoParams): void {
|
|
initUserProfile(userInfo: UserInfoParams): void {
|
|
this._userInfo = {
|
|
this._userInfo = {
|
|
|
|
+ id: userInfo.id,
|
|
RoomId: userInfo.roomId,
|
|
RoomId: userInfo.roomId,
|
|
Role: userInfo.role,
|
|
Role: userInfo.role,
|
|
UserId: userInfo.userId,
|
|
UserId: userInfo.userId,
|
|
Avatar: userInfo.avatar,
|
|
Avatar: userInfo.avatar,
|
|
Nickname:
|
|
Nickname:
|
|
decodeURIComponent(userInfo.nickname) || `用户[${userInfo.userId}]`,
|
|
decodeURIComponent(userInfo.nickname) || `用户[${userInfo.userId}]`,
|
|
- IsClient: userInfo.isClient,
|
|
|
|
|
|
+ IsClient: Boolean(userInfo.isClient),
|
|
IsMuted: true,
|
|
IsMuted: true,
|
|
IsWords: true,
|
|
IsWords: true,
|
|
Order: userInfo.role === 'leader' ? 0 : 1,
|
|
Order: userInfo.role === 'leader' ? 0 : 1,
|
|
@@ -50,36 +53,29 @@ export class RoomService {
|
|
IsOnline: true,
|
|
IsOnline: true,
|
|
};
|
|
};
|
|
}
|
|
}
|
|
- async handleUserOnline() {
|
|
|
|
- this._userInfo.IsOnline = true;
|
|
|
|
- if (this._userId && this._roomId) {
|
|
|
|
|
|
+ async handleUserOnline(socket: Socket) {
|
|
|
|
+ if (socket.data.user) {
|
|
|
|
+ socket.data.user.IsOnline = true;
|
|
await this.userService.updateUserOnlineState(
|
|
await this.userService.updateUserOnlineState(
|
|
- this._roomId,
|
|
|
|
- this._userId,
|
|
|
|
|
|
+ socket,
|
|
|
|
+ socket.data.user.RoomId,
|
|
|
|
+ socket.data.user.UserId,
|
|
true,
|
|
true,
|
|
);
|
|
);
|
|
- const roomUsers = await this.userService.getRoomUsers(this._roomId);
|
|
|
|
- this.isJoin &&
|
|
|
|
- this.socketGateway._socket.to(this._roomId).emit('action', {
|
|
|
|
- type: 'rooms-status',
|
|
|
|
- members: roomUsers,
|
|
|
|
- });
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- async handleUserOffline() {
|
|
|
|
- this._userInfo.IsOnline = false;
|
|
|
|
- if (this._userId && this._roomId) {
|
|
|
|
|
|
+ async handleUserOffline(socket: Socket) {
|
|
|
|
+ await this._sleep(500);
|
|
|
|
+ if (socket.data.user) {
|
|
|
|
+ socket.data.user.IsOnline = false;
|
|
await this.userService.updateUserOnlineState(
|
|
await this.userService.updateUserOnlineState(
|
|
- this._roomId,
|
|
|
|
- this._userId,
|
|
|
|
|
|
+ socket,
|
|
|
|
+ socket.data.user.RoomId,
|
|
|
|
+ socket.data.user.UserId,
|
|
false,
|
|
false,
|
|
);
|
|
);
|
|
- const roomUsers = await this.userService.getRoomUsers(this._roomId);
|
|
|
|
- this.socketGateway._socket.to(this._roomId).emit('action', {
|
|
|
|
- type: 'rooms-status',
|
|
|
|
- members: roomUsers,
|
|
|
|
- });
|
|
|
|
|
|
+ await this.handleRoomStatusAction(socket);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -88,8 +84,13 @@ export class RoomService {
|
|
* @param userInfo
|
|
* @param userInfo
|
|
*/
|
|
*/
|
|
|
|
|
|
- async handleUserJoin(userInfo: UserInfoParams): Promise<void> {
|
|
|
|
|
|
+ async handleUserJoin(
|
|
|
|
+ socket: Socket,
|
|
|
|
+ userInfo: UserInfoParams,
|
|
|
|
+ ): Promise<void> {
|
|
this.initUserProfile(userInfo);
|
|
this.initUserProfile(userInfo);
|
|
|
|
+ socket.data.user = this._userInfo;
|
|
|
|
+ await this.handleUserOnline(socket);
|
|
let blockJoin = false;
|
|
let blockJoin = false;
|
|
if (this._roomId?.length && this._userId?.length) {
|
|
if (this._roomId?.length && this._userId?.length) {
|
|
//房主设置房间配置
|
|
//房主设置房间配置
|
|
@@ -106,7 +107,7 @@ export class RoomService {
|
|
);
|
|
);
|
|
} else {
|
|
} else {
|
|
blockJoin = true;
|
|
blockJoin = true;
|
|
- this.socketGateway._socket.emit('action', {
|
|
|
|
|
|
+ socket.emit('action', {
|
|
type: 'invalid-master',
|
|
type: 'invalid-master',
|
|
code: 303,
|
|
code: 303,
|
|
});
|
|
});
|
|
@@ -124,7 +125,7 @@ export class RoomService {
|
|
} else {
|
|
} else {
|
|
const updated = await this.userService.updateUsers(this._userInfo);
|
|
const updated = await this.userService.updateUsers(this._userInfo);
|
|
if (!updated) {
|
|
if (!updated) {
|
|
- this.socketGateway._socket.emit('action', {
|
|
|
|
|
|
+ socket.emit('action', {
|
|
type: 'error',
|
|
type: 'error',
|
|
code: 405,
|
|
code: 405,
|
|
});
|
|
});
|
|
@@ -136,12 +137,12 @@ export class RoomService {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const roomUsers = await this.userService.getRoomUsers(this._roomId);
|
|
const roomUsers = await this.userService.getRoomUsers(this._roomId);
|
|
- this.socketGateway._socket.emit('join', {
|
|
|
|
- user: this._userInfo,
|
|
|
|
|
|
+ socket.emit('join', {
|
|
|
|
+ user: socket.data.user,
|
|
members: roomUsers,
|
|
members: roomUsers,
|
|
});
|
|
});
|
|
- if (!this._userInfo.IsClient) {
|
|
|
|
- this.socketGateway._socket.broadcast.to(this._roomId).emit('action', {
|
|
|
|
|
|
+ if (!socket.data.user.IsClient) {
|
|
|
|
+ socket.broadcast.to(socket.data.user.RoomId).emit('action', {
|
|
type: 'user-join',
|
|
type: 'user-join',
|
|
user: this._userInfo,
|
|
user: this._userInfo,
|
|
members: roomUsers,
|
|
members: roomUsers,
|
|
@@ -149,12 +150,12 @@ export class RoomService {
|
|
}
|
|
}
|
|
this.isJoin = true;
|
|
this.isJoin = true;
|
|
this.logger.log(
|
|
this.logger.log(
|
|
- JSON.stringify(this._userInfo),
|
|
|
|
- `join-user-${this._userInfo.Role}`,
|
|
|
|
|
|
+ JSON.stringify(socket.data.user),
|
|
|
|
+ `join-user-${socket.data.user.Role}`,
|
|
);
|
|
);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- this.socketGateway._socket.emit('action', { type: 'error', code: 403 });
|
|
|
|
|
|
+ socket.emit('action', { type: 'error', code: 403 });
|
|
this.logger.warn(`403:not roomId and userId`, 'join-error');
|
|
this.logger.warn(`403:not roomId and userId`, 'join-error');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -162,50 +163,106 @@ export class RoomService {
|
|
* 房间action大通道
|
|
* 房间action大通道
|
|
* @param message
|
|
* @param message
|
|
*/
|
|
*/
|
|
- async handleUserAction(message: any) {
|
|
|
|
- this.actionsService.handleAllAction(message);
|
|
|
|
|
|
+ async handleUserAction(socket: Socket, message: any) {
|
|
|
|
+ this.actionsService.handleAllAction(socket, message);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 房间sync大通道
|
|
* 房间sync大通道
|
|
* @param message
|
|
* @param message
|
|
*/
|
|
*/
|
|
- async handleSyncAction(message: any) {
|
|
|
|
- this.socketGateway._socket.broadcast.to(this._roomId).emit('sync', message);
|
|
|
|
|
|
+ async handleSyncAction(socket: Socket, message: any) {
|
|
|
|
+ socket.broadcast.to(this._roomId).emit('sync', message);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 房间paint大通道
|
|
* 房间paint大通道
|
|
* @param message
|
|
* @param message
|
|
*/
|
|
*/
|
|
- async handlePaintAction(message: any) {
|
|
|
|
- this.socketGateway._socket.broadcast
|
|
|
|
- .to(this._roomId)
|
|
|
|
- .emit('paint', message);
|
|
|
|
|
|
+ async handlePaintAction(socket: Socket, message: any) {
|
|
|
|
+ socket.broadcast.to(this._roomId).emit('paint', message);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 房间T人
|
|
* 房间T人
|
|
* @param message
|
|
* @param message
|
|
*/
|
|
*/
|
|
- async handleKickAction(userId: string) {
|
|
|
|
- await this.userService.deleteRoomUser(this._roomId, userId);
|
|
|
|
- this.socketGateway._socket.broadcast.to(this._roomId).emit('action', {
|
|
|
|
- type: 'kick-user',
|
|
|
|
- data: {
|
|
|
|
- userId: userId,
|
|
|
|
- },
|
|
|
|
|
|
+ async handleKickAction(socket: Socket, RoomId: string, userId: string) {
|
|
|
|
+ const delUser = await this.userService.getUsersByUserId(RoomId, userId);
|
|
|
|
+ this.logger.warn(
|
|
|
|
+ `RoomId: ${RoomId},userId:${userId} socketId:${delUser.id}`,
|
|
|
|
+ 'kick-user',
|
|
|
|
+ );
|
|
|
|
+ const roomUsers = await this.userService.getRoomUsers(RoomId);
|
|
|
|
+ const filterRoomUser = roomUsers.filter((i) => i.UserId !== userId);
|
|
|
|
+ if (delUser) {
|
|
|
|
+ socket.data.isKick = true;
|
|
|
|
+ this.socketGateway.server.sockets.sockets.forEach((soc) => {
|
|
|
|
+ if (soc.id === delUser.id) {
|
|
|
|
+ soc.disconnect(true);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ const res = await this.userService.deleteRoomUser(RoomId, userId);
|
|
|
|
+ // console.log('kick-user', delUser.id, RoomId, userId);
|
|
|
|
+ if (res) {
|
|
|
|
+ this.socketGateway.server.to(RoomId).emit('action', {
|
|
|
|
+ type: 'user-leave',
|
|
|
|
+ user: delUser,
|
|
|
|
+ members: filterRoomUser,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 房间全员状态更新
|
|
|
|
+ * @param message
|
|
|
|
+ */
|
|
|
|
+ async handleRoomStatusAction(socket: Socket) {
|
|
|
|
+ const roomId = socket.data.user.RoomId;
|
|
|
|
+ const roomUsers = await this.userService.getRoomUsers(roomId);
|
|
|
|
+ this.socketGateway.server.to(roomId).emit('action', {
|
|
|
|
+ type: 'rooms-status',
|
|
|
|
+ members: roomUsers,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
/**
|
|
|
|
+ * 房间主动退出逻辑
|
|
|
|
+ * @param message
|
|
|
|
+ */
|
|
|
|
+ async handleExitAction(socket: Socket, message: any) {
|
|
|
|
+ console.log('socket', socket.data.user);
|
|
|
|
+ const roomId = message?.roomId || socket.data.user?.RoomId;
|
|
|
|
+ const userId = message?.userId || socket.data.user?.UserId;
|
|
|
|
+ if (roomId && userId) {
|
|
|
|
+ const delUser = await this.userService.getUsersByUserId(roomId, userId);
|
|
|
|
+ this.logger.warn(
|
|
|
|
+ `RoomId: ${roomId},userId:${userId} socketId:${delUser.id}`,
|
|
|
|
+ 'room-exit',
|
|
|
|
+ );
|
|
|
|
+ const roomUsers = await this.userService.getRoomUsers(roomId);
|
|
|
|
+ const filterRoomUser = roomUsers.filter((i) => i.UserId !== userId);
|
|
|
|
+ const res = await this.userService.deleteRoomUser(roomId, userId);
|
|
|
|
+ console.log('user-exit', delUser.id, roomId, userId);
|
|
|
|
+ if (res) {
|
|
|
|
+ this.socketGateway.server.to(roomId).emit('action', {
|
|
|
|
+ type: 'user-leave',
|
|
|
|
+ user: delUser,
|
|
|
|
+ members: filterRoomUser,
|
|
|
|
+ });
|
|
|
|
+ socket.disconnect(true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
* 解散房间
|
|
* 解散房间
|
|
*/
|
|
*/
|
|
|
|
|
|
- async handleRoomDismiss(): Promise<void> {
|
|
|
|
- await this.userService.delRoom(this._roomId);
|
|
|
|
- await this.userService.delRoomConfig(this._roomId);
|
|
|
|
- this.socketGateway._socket
|
|
|
|
- .to(this._roomId)
|
|
|
|
|
|
+ async handleRoomDismiss(RoomId: string): Promise<void> {
|
|
|
|
+ await this.userService.delRoom(RoomId);
|
|
|
|
+ await this.userService.delRoomConfig(RoomId);
|
|
|
|
+ this.socketGateway.server
|
|
|
|
+ .to(RoomId)
|
|
.emit('action', { type: 'leader-dismiss' });
|
|
.emit('action', { type: 'leader-dismiss' });
|
|
}
|
|
}
|
|
}
|
|
}
|