52ABP-Angular-即时聊天文档

操作手册

效果图

image-20220326143109465

开启聊天功能

image-20220326145256701

选择聊天用户

选择好友后默认添加对方好友

  • 不可添加自己为好友
  • 已添加为好友不可重复添加

image-20220326145413995

发送即时消息

选择用户后可添加至列表,对应展示用户在线状态

点击选择用户后发送即时消息

image-20220326145820474

接收即时消息

列表可查看用户消息提示

image-20220326145716749

image-20220326151348001

消息回复

选择对应用户消息框可进行恢复

image-20220326151443793

image-20220326151525097

会话小窗

小窗可在其他页面操作时进行即时聊天,默认为即时聊天窗口当前选择的用户

image-20220326151608254

操作栏按钮

  • 链接聊天主页:可快速打开即时聊天tab页面
  • 好友列表:可打开侧边抽屉查看好友列表,方便快速切换聊天用户

image-20220326151738885

image-20220326151916195

代码

功能实现使用SignalR进行前后端通信,并通过事件触发对应的操作

选择用户

选择用户会对应添加好友

  /**
   * 添加用户信息
   * @param userName
   * @param tenantId
   */
  openSearchModal(userName: string, tenantId?: number): void {
    const modal = this.modalService.create({
      nzTitle: '查询用户',
      nzContent: LookupComponent,
      nzComponentParams: {
        filterText: this.userNameFilter,
        tenantId: this.appSession.tenantId,
        dataSource: (skipCount: number, maxResultCount: number, filter: string, tenantId?: number) => {
          const input = new CommonLookupFindUsersInput();
          input.filterText = filter;
          input.maxResultCount = maxResultCount;
          input.skipCount = skipCount;
          input.tenantId = tenantId;
          return this._commonLookupService.findUsers(input);
        },
      },
      nzFooter: null,
    });
    // Return a result when closed
    modal.afterClose.subscribe(result => {
      if (result === undefined) {
        return;
      }
      const userId = result.value;
      const input = new CreateFriendshipRequestInput();
      input.userId = parseInt(userId);
      input.tenantId = this.appSession.tenant ? this.appSession.tenant.id : null;

      this._friendshipService.createFriendshipRequest(input).subscribe(() => {
        this.userNameFilter = '';
        this.abpSignalr.getFriendsAndSettings();
        this.cd.detectChanges();
      });
    });
  }

后端接口:

FriendshipAppService:CreateFriendshipRequest()

/// <summary>
/// 添加好友关系
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<FriendDto> CreateFriendshipRequest(CreateFriendshipRequestInput input)
{
    // ...
}

发送消息

发送消息通过调用ChatHub-sendMessages

  sendMessage(event?: any): void {
    if (event) {
      event.preventDefault();
      event.stopPropagation();
    }
    if (!this.chatMessage) {
      return;
    }
    this.sendingMessage = true;
    const tenancyName = this.appSession.tenant ? this.appSession.tenant.tenancyName : null;
    this.abpSignalr.sendMessage(
      {
        tenantId: this.selectedUser.friendTenantId,
        userId: this.selectedUser.friendUserId,
        message: this.chatMessage,
        tenancyName: tenancyName,
        userName: this.appSession.user.userName,
        // profilePictureId: this.appSession.user.profilePictureId,
      },
      () => {
        this.chatMessage = '';
        this.sendingMessage = false;
        this.cd.detectChanges();
        this.chatMessage = '';
        this.sendingMessage = false;
        this.cd.detectChanges();
      },
    );
  }

后端ChatHub-SendMessage

public async Task<string> SendMessage(SendChatMessageInput input)
{
    // ...
}

接收消息

注册接收消息的事件,ChatComponent

registerEvents(): void {
   const self = this;
   abp.event.on('app.chat.messageReceived', message => {
     self._zone.run(() => {
     });
   });
	//....
}

AbpSignalrService

registerChatEvents(connection): void {
    const self = this;
    self.getFriendsAndSettings();
    connection.on('getChatMessage', message => {
      self.onMessageReceived(message);
      abp.event.trigger('app.chat.messageReceived', message);
    });
}
/**
   * 收到消息
   * @param message
   */
  onMessageReceived(message) {
    const self = this;
    // 判断接收人是否存在
    const user = self.getFriendOrNull(message.targetUserId, message.targetTenantId);
    if (!user) {
      return;
    }
    console.log('message', message);
    user.messages = user.messages || [];
    user.messages.push(message);
    if (message.side === 2) {
      // ChatSide.Receiver
      user.unreadMessageCount += 1;
      message.readState = ChatMessageReadState.Unread;
      self.triggerUnreadMessageCountChangeEvent();

      if (
        self.selectedUser !== null &&
        user.friendTenantId === self.selectedUser.friendTenantId &&
        user.friendUserId === self.selectedUser.friendUserId
      ) {
        self.markAllUnreadMessagesOfUserAsRead(user);
      }
    }
    this.friendsSubject.next(this.friends);
    this.selectUserSubject.next(this.selectedUser);
  }