仓库
数据库
conversations 会话表
群:表示群聊有效
| 最后一次消息时间 | 会话名称(群) | 会话头像(群) | 最后一个消息内容 | 是否群 | 消息id集合 | 成员 |
|---|---|---|---|---|---|---|
| lastMessageAt | name | image | lastMessage | isGroup | messages | participants |
messages 聊天列表
| 文字聊天内容 | 图片内容 | 发送者id | 接收者id(群id或userid) | 所属会话id | 未读消息id集合 |
|---|---|---|---|---|---|
| body | image | senderId | receiverId | conversationId | unReads |
users 用户表
| 昵称 | 用户名 | 背景图 | 密码 | 头像 | 个性签名 | 会话id集合 |
|---|---|---|---|---|---|---|
| name | username | image | password | avatar | remark | conversationIds |
逻辑说明
1.会话数据 - 查询用户数据同时关联查询会话信息及会话下未读消息。
2.创建会话 - 群聊则直接添加成员创建会话,单聊则根据双方id创建会话
3.删除会话 - 删除会话仅是users下的conversationIds集合中移除,删除用户或解散群则删除会话表数据且关联删除messages中的数据
4.创建聊天消息
单聊 - reciverid 就是userid 需要根据sendid与reviverid创建会话再进行聊天 群聊 - reciverid 就是群Id 因为会话需要提前创建好所以可以直接进行聊天
消息推送 - 单聊推送id直接是reciverid就可以,群聊则需要先查询出群成员再依次发送给每个群成员
更新会话中的lastMessage,lastMessageAt,messages.
5.定时任务 聊天记录超过七天则自动删除
webSocket
// 创建ws 模块用于推送
nest g res ws // 创建 ws.gateway.ts
import { WebSocketGateway, SubscribeMessage, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit, WebSocketServer } from '@nestjs/websockets';
import { Logger } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
import { WsService } from './ws.service';
import { MessageType } from 'src/message/entities/message.entity';
@WebSocketGateway({ core: true })
export class WsGateway implements OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit {
constructor(private readonly wsService: WsService) { }
// server 实例
@WebSocketServer()
server: Server;
/**
* 用户连接上
* @param client client
* @param args
*/
handleConnection(client: Socket, ...args: any[]) {
// 注册用户
const token = client.handshake?.auth?.token ?? client.handshake?.headers?.authorization
return this.wsService.login(client, token)
}
/**
* 用户断开
* @param client client
*/
handleDisconnect(client: Socket) {
// 移除数据 socketID
this.wsService.logout(client)
}
@SubscribeMessage('message')
handleMessage(client: Socket, payload: { participants: string[], message: MessageType }): void {
this.wsService.sendMessage(client, payload)
}
@SubscribeMessage('join')
handleJoin(client: Socket, payload: any): void {
// 加入房间
client.join(payload);
}
/**
* 初始化
* @param server
*/
afterInit(server: Server) {
Logger.log('websocket init... port: ' + process.env.PORT)
this.wsService.server = server;
// 重置 socketIds
this.wsService.resetClients()
}
}