从零开始开发聊天APP (后端篇三)

200 阅读2分钟

仓库

数据库

github.com/NewSmallObj…

conversations 会话表

群:表示群聊有效

最后一次消息时间会话名称(群)会话头像(群)最后一个消息内容是否群消息id集合成员
lastMessageAtnameimagelastMessageisGroupmessagesparticipants

messages 聊天列表

文字聊天内容图片内容发送者id接收者id(群id或userid)所属会话id未读消息id集合
bodyimagesenderIdreceiverIdconversationIdunReads

users 用户表

昵称用户名背景图密码头像个性签名会话id集合
nameusernameimagepasswordavatarremarkconversationIds

逻辑说明

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()
  }
}