docs/en/modules/chat.md
//[doc-seo]
{
"Description": "Discover how to implement real-time messaging in your application with the ABP Chat Module. Installation made easy via ABP Suite or CLI."
}
You must have an ABP Team or a higher license to use this module.
This module implements real time messaging between users for an application.
See the module description page for an overview of the module features.
To download the source-code of the Chat module, you can use ABP Suite or you can use the ABP CLI with the following command:
abp get-source Volo.Chat
Chat module is not installed in the startup templates. So, it needs to be installed manually. There are two ways of installing a module into your application.
ABP Suite allows adding a module to a solution using Add to your solution option in modules list.
If you modified your solution structure, adding module using ABP Suite might not work for you. In such cases, chat module can be added to a solution manually.
In order to do that, add packages listed below to matching project on your solution. For example, Volo.Chat.Application package to your {ProjectName}.Application.csproj like below;
<PackageReference Include="Volo.Chat.Application" Version="x.x.x" />
After adding the package reference, open the module class of the project (eg: {ProjectName}ApplicationModule) and add the below code to the DependsOn attribute.
[DependsOn(
//...
typeof(ChatApplicationModule)
)]
If you are using Blazor Web App, you need to add the
Volo.Chat.Blazor.WebAssemblypackage to the {ProjectName}.Blazor.Client.csproj project and add theVolo.Chat.Blazor.Serverpackage to the {ProjectName}.Blazor.csproj project.
The Volo.Chat.SignalR package must be added according to your project structure:
If database provider of your project is EntityFrameworkCore, use modelBuilder.ConfigureChat() to configure database tables in your project's DbContext.
See Microsoft SignalR Authentication and Authorization and Microsoft SignalR Security documentations.
In standard web APIs, bearer tokens are sent in an HTTP header. However, SignalR is unable to set these headers in browsers when using some transports. When using WebSockets and Server-Sent Events, the token is transmitted as a query string parameter. To support this on the server, additional configuration is required.
Here is a sample configuration for this:
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();
});
When Web & API tiers are separated, it is impossible to directly send a server-to-client message from the HTTP API. This is also true for a microservice architected application. Chat Module uses the distributed event bus to deliver the message from API application to the web application, then to the client.
If your project has such an architecture (example: MVC + tiered option), then you need a Distributed Event Bus. See related ABP documentation to understand Distributed Event Bus system in ABP. Also see RabbitMQ Integration documentation if your choice is to use RabbitMQ.
This module follows the module development best practices guide and consists of several NuGet and NPM packages. See the guide if you want to understand the packages and relations between them.
You can visit Chat module package list page to see list of packages related with this module.
The Chat.Enable feature is disabled by default. Enable it for a tenant or edition before granting chat permissions.
The module defines the following permissions:
Chat.Messaging: Allows a user to open the chat page and exchange messages. A message can only be sent if the target user also has this permission.Chat.Searching: A child permission of Chat.Messaging. It allows a user to start a conversation with a user who is not already in the conversation history. Without this permission, the user can continue existing conversations.Chat.SettingManagement: Allows a user to manage the chat settings.This is the page that users send messages to each other.
Message text is required. By default, it must contain between 1 and 4,096 characters. The conversation API returns the newest messages first; the built-in user interfaces reverse that result to display messages in chronological order.
The following settings control deletion behavior:
| Setting | Default | Description |
|---|---|---|
Volo.Chat.Messaging.DeletingMessages | Enabled | Enabled allows deletion at any time, Disabled prevents deletion, and EnabledWithDeletionPeriod allows deletion only during the configured period after the message is created. |
Volo.Chat.Messaging.MessageDeletionPeriod | 0 | Deletion period in seconds when message deletion is set to EnabledWithDeletionPeriod. |
Volo.Chat.Messaging.DeletingConversations | Enabled | Enables conversation deletion. It is effective only when message deletion is set to Enabled. |
Deleting a message removes the shared message and both users' message records. Deleting a conversation removes both users' conversation records and all messages between them. These operations are shared deletions, not a "hide for me" operation. Deletion notifications are sent through the real-time channel.
An icon that shows unread message count of the user and leads to chat page when clicked is added to navigation menu.
Message (aggregate root): Represents a chat message. Implements IMultiTenant.
Text: Message content.IsAllRead: Message read information.ReadTime: Message read time information.ChatUser (aggregate root): Represents a chat user. Implements IUser and IUpdateUserData interfaces.UserMessage: is created for each side (sender and receiver) of a message. Implements IMultiTenant and IAggregateRoot interfaces.
ChatMessageId: Id of related Message.UserId: Id of related ChatUser.TargetUserId: Id of other related ChatUser.Side: States that if it is a send message or received message.IsRead: Read information.ReadTime: Read time information.Conversation: is created for each side of a conversation between users. Implements IMultiTenant and IAggregateRoot interfaces.
UserId: Id of related ChatUser.TargetUserId: Id of other related ChatUser.LastMessageSide: States the side of the latest message (send or received).LastMessage: Content of the last message in the conversation.LastMessageDate: Date of the last message in the conversation.UnreadMessageCount: Count of unread messages in the conversation.This module follows the Repository Best Practices & Conventions guide.
Following custom repositories are defined for this module:
IConversationRepositoryIUserMessageRepositoryIChatUserRepositoryIMessageRepositoryMessagingManagerConversationAppService (implements IConversationAppService): Used to send messages, get conversation between users and mark a conversation as read.SettingsAppService (implements ISettingsAppService): Used to save chat settings.ContactAppService (implements IContactAppService): Used to get list of contacts and total unread message count of a user.DistributedEventBusRealTimeChatMessageSender (implements IRealTimeChatMessageSender): Used to publish chat messages to distributed event bus.SignalRRealTimeChatMessageSender (implements IRealTimeChatMessageSender): Used to send messages to target SignalR client.All tables/collections use the Chat prefix by default. Set static properties on the ChatDbProperties class if you need to change the table prefix or set a schema name (if supported by your database provider).
This module uses Chat for the connection string name. If you don't define a connection string with this name, it fallbacks to the Default connection string.
See the connection strings documentation for details.
In order to configure the application to use the chat module, you first need to import provideChatConfig from @volo/abp.ng.chat/config to the root application configuration. Then, you will need to append it to the providers array.
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideChatConfig } from '@volo/abp.ng.chat/config';
export const appConfig: ApplicationConfig = {
providers: [
// ...
provideChatConfig(),
],
};
The chat module should be imported and lazy-loaded in your routing array. It exports a createRoutes function from @volo/abp.ng.chat.
// app.routes.ts
import { Routes } from '@angular/router';
const APP_ROUTES: Routes = [
// ...
{
path: 'chat',
loadChildren: () =>
import('@volo/abp.ng.chat').then(c => c.createRoutes()),
},
];
The Angular chat route uses the Chat.ChatComponent replacement key and ChatComponent as its default component. See the Angular component replacement documentation if you need to replace the page.
Chat module services and models are generated via generate-proxy command of the ABP CLI. If you need the module's proxies, you can run the following command in the Angular project directory:
abp generate-proxy --module chat
The Chat module remote endpoint URLs can be configured in the environment files.
export const environment = {
// other configurations
apis: {
default: {
url: 'default url here',
},
Chat: {
url: 'Chat remote url here',
signalRUrl: 'Chat signalR remote url here',
},
// other api configurations
},
};
The Chat module remote URL configurations shown above are optional.
If you don't set the
signalRUrl,Chat.urlwill be used as fallback. If you don't set theChatproperty, thedefault.urlwill be used as fallback.
The SignalR base URL can be configured with the option type that matches the UI package:
| UI package | Option type | Fallback when SignalrUrl is not set |
|---|---|---|
| Blazor Server | ChatBlazorServerOptions | The current application URL. |
| Blazor WebAssembly | ChatBlazorWebAssemblyOptions | AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl. |
| Blazor MAUI | ChatBlazorMauiBlazorOptions | AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl. |
| MudBlazor Server | ChatBlazorMudBlazorServerOptions | The current application URL. |
| MudBlazor WebAssembly | ChatBlazorMudBlazorWebAssemblyOptions | AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl. |
| MudBlazor MAUI | ChatBlazorMudBlazorMauiBlazorOptions | AbpRemoteServiceOptions.RemoteServices.Default.BaseUrl. |
The module appends the /signalr-hubs/chat path to the resolved base URL.
For example, the Chat module remote endpoint URL can be configured for Blazor WebAssembly via the ChatBlazorWebAssemblyOptions:
Configure<ChatBlazorWebAssemblyOptions>(options =>
{
options.SignalrUrl = builder.Configuration["RemoteServices:Chat:BaseUrl"];
});
"RemoteServices": {
"Default": {
"BaseUrl": "Default url here"
},
"Chat": {
"BaseUrl": "Chat remote url here"
}
},
If you don't set the
BaseUrl, theDefault.BaseUrlwill be used as fallback.
The module defines the following Event Transfer Object types for real-time operations:
| Event Transfer Object | Operation | SignalR client method |
|---|---|---|
ChatMessageEto | A message is sent. | ReceiveMessage |
ChatDeletedMessageEto | A message is deleted. | DeleteMessage |
ChatDeletedConversationEto | A conversation is deleted. | DeleteConversation |
The default application-layer implementation of IRealTimeChatMessageSender publishes these events to the distributed event bus. The Volo.Chat.SignalR package replaces that implementation in the SignalR host, handles the distributed events and sends them to the target user through the corresponding SignalR client method. See the standard distributed events for more information about distributed events.