项目

聊天模块 (专业版)

使用本模块需拥有 ABP Team 或更高版本授权

该模块为应用程序实现用户间的实时消息传递功能。

请参阅模块介绍页面了解模块功能概览。

要下载聊天模块的源代码,您可以使用 ABP Suite 或通过以下 ABP CLI 命令:

abp get-source Volo.Chat

安装方法

聊天模块未预装在 启动模板 中,需要手动安装。有两种方式可将模块安装到您的应用中。

安装步骤

1. 使用 ABP Suite

ABP Suite 允许通过模块列表中的添加到解决方案选项来添加模块。 suite-chat-add

2. 手动安装

如果您修改了解决方案结构,使用 ABP Suite 添加模块可能无法正常工作。这种情况下,可以手动将聊天模块添加到解决方案。

具体操作:将以下列出的包添加到解决方案中对应的项目。例如,将 Volo.Chat.Application 包添加到您的 {项目名称}.Application.csproj 中,如下所示:

<PackageReference Include="Volo.Chat.Application" Version="x.x.x" />

添加包引用后,打开项目的模块类(例如:{项目名称}ApplicationModule)并在 DependsOn 属性中添加以下代码:

[DependsOn(
  //...
  typeof(ChatApplicationModule)
)]

如果使用 Blazor Web App,需要将 Volo.Chat.Blazor.WebAssembly 包添加到 {项目名称}.Blazor.Client.csproj 项目,并将 Volo.Chat.Blazor.Server 包添加到 {项目名称}.Blazor.csproj 项目。

Volo.Chat.SignalR 包需要根据项目结构进行添加:

  • MVC
    • 分层架构:{项目名称}.HttpApi.Host 项目
  • Blazor Server
    • 统一后端:{项目名称}.Blazor
    • 独立认证服务器:{项目名称}.HttpApi.Host 项目
  • Blazor WebAssembly:{项目名称}.HttpApi.Host 项目
  • Blazor Web App
    • 统一后端:{项目名称}.Blazor
    • 独立认证服务器:{项目名称}.HttpApi.Host 项目
  • Angular:{项目名称}.HttpApi.Host 项目

如果项目使用 EntityFrameworkCore 数据库提供程序,请在项目的 DbContext 中使用 modelBuilder.ConfigureChat() 来配置数据库表。

配置说明

Angular 和 Blazor WebAssembly 项目的 SignalR 访问令牌配置

请参阅 Microsoft SignalR 认证与授权Microsoft SignalR 安全指南 文档。

在标准 Web API 中,承载令牌通过 HTTP 头部发送。但 SignalR 在使用某些传输方式时无法在浏览器中设置这些头部。使用 WebSockets 和 Server-Sent Events 时,令牌会以查询字符串参数的形式传输。为在服务器端支持此功能,需要进行额外配置。

以下是配置示例:

app.Use(async (httpContext, next) =>
{
    var accessToken = httpContext.Request.Query["access_token"];

    var path = httpContext.Request.Path;
    if (!string.IsNullOrEmpty(accessToken) &&
        (path.StartsWithSegments("/signalr-hubs/chat")))
    {
        httpContext.Request.Headers["Authorization"] = "Bearer " + accessToken;
    }

    await next();
});

为分布式架构项目添加分布式事件总线

当 Web 层与 API 层分离时,无法直接从 HTTP API 发送服务器到客户端的消息。这在微服务架构的应用中同样适用。聊天模块使用分布式事件总线将消息从 API 应用传递到 Web 应用,再传递给客户端。

如果您的项目采用此类架构(例如:MVC + 分层选项),则需要配置分布式事件总线。请参阅 相关 ABP 文档 了解 ABP 中的分布式事件总线系统。如果选择使用 RabbitMQ,请同时参阅 RabbitMQ 集成文档

包说明

本模块遵循 模块开发最佳实践指南,包含多个 NuGet 和 NPM 包。如需了解各包及其相互关系,请参阅该指南。

您可以访问聊天模块包列表页面查看与本模块相关的包列表。

用户界面

管理聊天功能

聊天模块定义了聊天功能,您需要启用该功能才能使用聊天服务。

chat-feature

聊天页面

这是用户相互发送消息的界面。

chat-page

导航栏聊天图标

导航菜单中会添加一个显示用户未读消息数量并在点击时跳转到聊天页面的图标。

chat-page

内部架构

领域层

实体与聚合根

  • Message(聚合根):代表聊天消息。实现 IMultiTenant 接口。
    • Text:消息内容
    • IsAllRead:消息已读状态
    • ReadTime:消息阅读时间
  • ChatUser(聚合根):代表聊天用户。实现 IUserIUpdateUserData 接口
  • UserMessage:为消息的发送方和接收方分别创建。实现 IMultiTenantIAggregateRoot 接口
    • ChatMessageId:关联 Message 的 ID
    • UserId:关联 ChatUser 的 ID
    • TargetUserId:关联另一方 ChatUser 的 ID
    • Side:标识是发送消息还是接收消息
    • IsRead:已读状态
    • ReadTime:阅读时间
  • Conversation:为用户间的每次对话双方创建。实现 IMultiTenantIAggregateRoot 接口
    • UserId:关联 ChatUser 的 ID
    • TargetUserId:关联另一方 ChatUser 的 ID
    • LastMessageSide:最新消息的方向(发送或接收)
    • LastMessage:对话中最后一条消息的内容
    • LastMessageDate:最后一条消息的日期
    • UnreadMessageCount:对话中未读消息数量

仓储

本模块遵循 仓储最佳实践与规范

为此模块定义了以下自定义仓储:

  • IConversationRepository
  • IUserMessageRepository
  • IChatUserRepository
  • IMessageRepository

领域服务

  • MessagingManager

应用层

应用服务

  • ConversationAppService(实现 IConversationAppService):用于发送消息、获取用户间对话以及标记对话为已读
  • SettingsAppService(实现 ISettingsAppService):用于保存聊天设置
  • ContactAppService(实现 IContactAppService):用于获取联系人列表和用户总未读消息数
  • DistributedEventBusRealTimeChatMessageSender(实现 IRealTimeChatMessageSender):用于将聊天消息发布到分布式事件总线
  • SignalRRealTimeChatMessageSender(实现 IRealTimeChatMessageSender):用于向目标 SignalR 客户端发送消息

数据库提供程序

通用配置

表/集合前缀与架构

所有表/集合默认使用 Chat 前缀。如需更改表前缀或设置架构名称(如果数据库提供程序支持),请在 ChatDbProperties 类上设置静态属性。

连接字符串

本模块使用 Chat 作为连接字符串名称。如果未定义此名称的连接字符串,将回退使用 Default 连接字符串。

详情请参阅连接字符串文档

Entity Framework Core

数据表
  • ChatUsers
  • ChatMessages
  • ChatUserMessages
  • ChatConversations

MongoDB

集合
  • ChatUsers
  • ChatMessages
  • ChatUserMessages
  • ChatConversations

Angular UI

安装配置

要将应用配置为使用聊天模块,首先需要从 @volo/abp.ng.chat/config 导入 provideChatConfig,然后将其添加到 appConfig 数组中。

// app.config.ts
import { provideChatConfig } from '@volo/abp.ng.chat/config';

export const appConfig: ApplicationConfig = {
  providers: [
    // ...
    provideChatConfig(),
  ],
};

聊天模块需要在路由数组中导入并配置为懒加载。它提供了静态的 createRoutes 方法进行配置,可从 @volo/abp.ng.chat 导入。

// app.routes.ts
const APP_ROUTES: Routes = [
  // ...
  {
    path: 'chat',
    loadChildren: () =>
      import('@volo/abp.ng.chat').then(c => c.createRoutes(/* 配置选项 */)),
  },
];

服务/模型

聊天模块的服务和模型通过 ABP CLIgenerate-proxy 命令生成。如需模块代理,可在 Angular 项目目录下运行以下命令:

abp generate-proxy --module chat

远程端点 URL

聊天模块的远程端点 URL 可在环境文件中配置。

export const environment = {
  // 其他配置
  apis: {
    default: {
      url: '默认 URL',
    },
    Chat: {
      url: '聊天远程 URL',
      signalRUrl: '聊天 SignalR 远程 URL',
    },
    // 其他 API 配置
  },
};

上述聊天模块远程 URL 配置为可选配置。

如果未设置 signalRUrl,将回退使用 Chat.url。如果未设置 Chat 属性,将回退使用 default.url

Blazor WebAssembly UI

远程端点 URL

聊天模块的远程端点 URL 可通过 ChatBlazorWebAssemblyOptions 进行配置。

Configure<ChatBlazorWebAssemblyOptions>(options =>
{
    options.SignalrUrl = builder.Configuration["RemoteServices:Chat:BaseUrl"];
});
"RemoteServices": {
  "Default": {
    "BaseUrl": "默认 URL"
  },
  "Chat": {
    "BaseUrl": "聊天远程 URL"
  }
},

如果未设置 BaseUrl,将回退使用 Default.BaseUrl

分布式事件

本模块定义了消息事件。当用户向另一用户发送新消息时,会发布该事件,事件传输对象类型为 ChatMessageEto。有关分布式事件的更多信息,请参阅标准分布式事件文档

在本文档中