mirror of
https://github.com/Stone-Red-Code/EchoHub.git
synced 2026-09-04 09:06:07 +02:00
- Updated EchoHubConnection to use ApiClient for token retrieval. - Introduced ValidationConstants for common validation patterns and limits. - Enhanced AuthDtos with refresh token support and expiration details. - Added new ChatDtos for channel creation and topic updates. - Created CommonDtos for error and paginated responses. - Implemented RefreshToken model for managing refresh tokens. - Modified JwtTokenService to generate and hash refresh tokens. - Updated AuthController to handle registration, login, token refresh, and logout with improved error handling. - Enhanced ChannelsController with channel creation, topic updates, and pagination for channel retrieval. - Added FilesController for file management with rate limiting. - Improved UsersController for profile updates and avatar uploads with validation. - Integrated rate limiting across controllers to manage request load. - Introduced FileValidationHelper for validating uploaded image files. - Updated database context to include RefreshToken and enforce unique constraints. - Enhanced ChatHub for improved channel and message handling with validation. - Updated Program.cs to configure rate limiting and CORS policies.
136 lines
4.2 KiB
C#
136 lines
4.2 KiB
C#
using EchoHub.Core.Constants;
|
|
using EchoHub.Core.DTOs;
|
|
using EchoHub.Core.Models;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
|
|
namespace EchoHub.Client.Services;
|
|
|
|
public sealed class EchoHubConnection : IAsyncDisposable
|
|
{
|
|
private readonly HubConnection _connection;
|
|
|
|
public event Action<MessageDto>? OnMessageReceived;
|
|
public event Action<string, string>? OnUserJoined;
|
|
public event Action<string, string>? OnUserLeft;
|
|
public event Action<ChannelDto>? OnChannelUpdated;
|
|
public event Action<UserPresenceDto>? OnUserStatusChanged;
|
|
public event Action<string>? OnError;
|
|
public event Action<string>? OnConnectionStateChanged;
|
|
|
|
public bool IsConnected => _connection.State == HubConnectionState.Connected;
|
|
|
|
public EchoHubConnection(string serverUrl, ApiClient apiClient)
|
|
{
|
|
var hubUrl = serverUrl.TrimEnd('/') + HubConstants.ChatHubPath;
|
|
|
|
_connection = new HubConnectionBuilder()
|
|
.WithUrl(hubUrl, options =>
|
|
{
|
|
options.AccessTokenProvider = () => apiClient.GetValidTokenAsync();
|
|
})
|
|
.WithAutomaticReconnect()
|
|
.Build();
|
|
|
|
RegisterHandlers();
|
|
|
|
_connection.Reconnecting += _ =>
|
|
{
|
|
OnConnectionStateChanged?.Invoke("Reconnecting...");
|
|
return Task.CompletedTask;
|
|
};
|
|
|
|
_connection.Reconnected += _ =>
|
|
{
|
|
OnConnectionStateChanged?.Invoke("Connected");
|
|
return Task.CompletedTask;
|
|
};
|
|
|
|
_connection.Closed += _ =>
|
|
{
|
|
OnConnectionStateChanged?.Invoke("Disconnected");
|
|
return Task.CompletedTask;
|
|
};
|
|
}
|
|
|
|
private void RegisterHandlers()
|
|
{
|
|
_connection.On<MessageDto>(nameof(Core.Contracts.IEchoHubClient.ReceiveMessage), message =>
|
|
{
|
|
OnMessageReceived?.Invoke(message);
|
|
});
|
|
|
|
_connection.On<string, string>(nameof(Core.Contracts.IEchoHubClient.UserJoined), (channelName, username) =>
|
|
{
|
|
OnUserJoined?.Invoke(channelName, username);
|
|
});
|
|
|
|
_connection.On<string, string>(nameof(Core.Contracts.IEchoHubClient.UserLeft), (channelName, username) =>
|
|
{
|
|
OnUserLeft?.Invoke(channelName, username);
|
|
});
|
|
|
|
_connection.On<ChannelDto>(nameof(Core.Contracts.IEchoHubClient.ChannelUpdated), channel =>
|
|
{
|
|
OnChannelUpdated?.Invoke(channel);
|
|
});
|
|
|
|
_connection.On<UserPresenceDto>(nameof(Core.Contracts.IEchoHubClient.UserStatusChanged), presence =>
|
|
{
|
|
OnUserStatusChanged?.Invoke(presence);
|
|
});
|
|
|
|
_connection.On<string>(nameof(Core.Contracts.IEchoHubClient.Error), message =>
|
|
{
|
|
OnError?.Invoke(message);
|
|
});
|
|
}
|
|
|
|
public async Task ConnectAsync()
|
|
{
|
|
OnConnectionStateChanged?.Invoke("Connecting...");
|
|
await _connection.StartAsync();
|
|
OnConnectionStateChanged?.Invoke("Connected");
|
|
}
|
|
|
|
public async Task DisconnectAsync()
|
|
{
|
|
await _connection.StopAsync();
|
|
OnConnectionStateChanged?.Invoke("Disconnected");
|
|
}
|
|
|
|
public async Task<List<MessageDto>> JoinChannelAsync(string channelName)
|
|
{
|
|
return await _connection.InvokeAsync<List<MessageDto>>("JoinChannel", channelName);
|
|
}
|
|
|
|
public async Task LeaveChannelAsync(string channelName)
|
|
{
|
|
await _connection.InvokeAsync("LeaveChannel", channelName);
|
|
}
|
|
|
|
public async Task SendMessageAsync(string channelName, string content)
|
|
{
|
|
await _connection.InvokeAsync("SendMessage", channelName, content);
|
|
}
|
|
|
|
public async Task<List<MessageDto>> GetHistoryAsync(string channelName, int count = HubConstants.DefaultHistoryCount)
|
|
{
|
|
return await _connection.InvokeAsync<List<MessageDto>>("GetChannelHistory", channelName, count);
|
|
}
|
|
|
|
public async Task UpdateStatusAsync(UserStatus status, string? statusMessage = null)
|
|
{
|
|
await _connection.InvokeAsync("UpdateStatus", status, statusMessage);
|
|
}
|
|
|
|
public async Task<List<UserPresenceDto>> GetOnlineUsersAsync(string channelName)
|
|
{
|
|
return await _connection.InvokeAsync<List<UserPresenceDto>>("GetOnlineUsers", channelName);
|
|
}
|
|
|
|
public async ValueTask DisposeAsync()
|
|
{
|
|
await _connection.DisposeAsync();
|
|
}
|
|
}
|