263 lines
9.0 KiB
C#
263 lines
9.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using CommunityToolkit.Mvvm.Messaging;
|
|
using gehGassi.Dto;
|
|
using gehGassi.Dto.Messages;
|
|
using gehGassiApp.Core.Interfaces;
|
|
using gehGassiApp.Core.Interfaces.Synchronization;
|
|
using gehGassiApp.Core.Messaging;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
|
|
namespace gehGassiApp.Core.Services
|
|
{
|
|
/// <summary>
|
|
/// Service der Daten vom AppHub des Servers empfangen kann
|
|
/// </summary>
|
|
public class AppHubService : IAppHubService
|
|
{
|
|
private string _baseAddress;
|
|
private HubConnection _connection;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="baseAddress">Basis-Adresse des Servers</param>
|
|
public AppHubService(string baseAddress)
|
|
{
|
|
_baseAddress = baseAddress;
|
|
if (_baseAddress.EndsWith("/"))
|
|
_baseAddress = _baseAddress.Substring(0, _baseAddress.Length - 1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connection zum Hub erstellen
|
|
/// </summary>
|
|
private void CreateConnection(string accessToken)
|
|
{
|
|
_connection = new HubConnectionBuilder().WithUrl($"{_baseAddress}/appHub", o =>
|
|
{
|
|
o.AccessTokenProvider = () => Task.FromResult(accessToken);
|
|
o.HttpMessageHandlerFactory = (message) =>
|
|
{
|
|
#if DEBUG
|
|
// bypass SSL certificate
|
|
if (message is HttpClientHandler clientHandler)
|
|
{
|
|
clientHandler.ServerCertificateCustomValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
|
|
}
|
|
#endif
|
|
return message;
|
|
};
|
|
}).WithAutomaticReconnect().Build();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setzen der Basis-Adresse des Servers
|
|
/// </summary>
|
|
/// <param name="baseAddress">Basis-Adresse</param>
|
|
public async Task SetBaseAddressAsync(string baseAddress)
|
|
{
|
|
_baseAddress = baseAddress;
|
|
if (_baseAddress.EndsWith("/"))
|
|
_baseAddress = _baseAddress.Substring(0, _baseAddress.Length - 1);
|
|
|
|
await DisconnectAsync();
|
|
}
|
|
|
|
public async Task ConnectAsync(string accessToken)
|
|
{
|
|
if (_connection != null && _connection.State == HubConnectionState.Connected) return;
|
|
if (_connection != null && _connection.State == HubConnectionState.Connecting) return;
|
|
if (_connection != null && _connection.State == HubConnectionState.Reconnecting) return;
|
|
|
|
//Buchen der Nachrichten
|
|
CreateConnection(accessToken);
|
|
|
|
_connection.On("AppUserChanged", async () => await AppUserChangedAsync());
|
|
_connection.On("NewsCategoriesChanged", async () => await NewsCategoriesChangedAsync());
|
|
_connection.On("ConversationMessageAdded", async (MessageDto messageDto) => await ConversationMessageAddedAsync(messageDto));
|
|
_connection.On("MessageAdded", async () => await MessageAddedAsync());
|
|
_connection.On("SystemMessageAdded", async () => await SystemMessageAddedAsync());
|
|
_connection.On("Logout", async () => await LogoutAsync());
|
|
|
|
try
|
|
{
|
|
|
|
await _connection.StartAsync().ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verbindung trennen
|
|
/// </summary>
|
|
/// <returns>Task</returns>
|
|
public async Task DisconnectAsync()
|
|
{
|
|
if (_connection != null)
|
|
{
|
|
try
|
|
{
|
|
await _connection.StopAsync();
|
|
await _connection.DisposeAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
}
|
|
}
|
|
|
|
//CreateConnection();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt zurück ob eine SignalR Verbindung besteht
|
|
/// </summary>
|
|
/// <returns>true wenn ja oder reconnecting, false sonst</returns>
|
|
public bool IsConnected()
|
|
{
|
|
if (_connection == null)
|
|
return false;
|
|
return _connection.State != HubConnectionState.Disconnected;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Buchen der Events eines App-Users
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des AppUsers</param>
|
|
/// <returns>Task</returns>
|
|
public async Task JoinAppUserAsync(string appUserId)
|
|
{
|
|
if(_connection == null || string.IsNullOrWhiteSpace(appUserId))
|
|
return;
|
|
|
|
if (_connection is { State: HubConnectionState.Connected })
|
|
{
|
|
await _connection.SendAsync("JoinAppUser", appUserId);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abbestellen der Events eines App-Users
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des AppUsers</param>
|
|
/// <returns>Task</returns>
|
|
public async Task LeaveAppUserAsync(string appUserId)
|
|
{
|
|
if (_connection == null || string.IsNullOrWhiteSpace(appUserId))
|
|
return;
|
|
|
|
if (_connection is { State: HubConnectionState.Connected })
|
|
{
|
|
await _connection.SendAsync("LeaveAppUser", appUserId);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Buchen der Events einer Konversation
|
|
/// </summary>
|
|
/// <param name="conversationId">Id der Konversation</param>
|
|
/// <param name="appUserId">Id des AppUsers</param>
|
|
/// <returns>Task</returns>
|
|
public async Task JoinConversationAsync(string conversationId, string appUserId)
|
|
{
|
|
if (_connection == null || string.IsNullOrWhiteSpace(appUserId) || string.IsNullOrWhiteSpace(conversationId))
|
|
return;
|
|
|
|
if (_connection is { State: HubConnectionState.Connected })
|
|
{
|
|
await _connection.SendAsync("JoinConversation", conversationId, appUserId);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Abbestellen der Events einer Konversation
|
|
/// </summary>
|
|
/// <param name="conversationId">Id der Konversation</param>
|
|
/// <param name="appUserId">Id des AppUsers</param>
|
|
/// <returns>Task</returns>
|
|
public async Task LeaveConversationAsync(string conversationId, string appUserId)
|
|
{
|
|
if (_connection == null || string.IsNullOrWhiteSpace(appUserId) || string.IsNullOrWhiteSpace(conversationId))
|
|
return;
|
|
|
|
if (_connection is { State: HubConnectionState.Connected })
|
|
{
|
|
await _connection.SendAsync("LeaveConversation", conversationId, appUserId);
|
|
}
|
|
}
|
|
|
|
#region EventHandler
|
|
|
|
/// <summary>
|
|
/// Handler wenn sich der App-User geändert hat
|
|
/// </summary>
|
|
/// <returns>Task</returns>
|
|
private async Task AppUserChangedAsync()
|
|
{
|
|
await Task.Delay(1);
|
|
WeakReferenceMessenger.Default.Send(new SignalRAppUserChangedMessage());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler wenn sich News-Kategorien geändert haben
|
|
/// </summary>
|
|
/// <returns>Task</returns>
|
|
private async Task NewsCategoriesChangedAsync()
|
|
{
|
|
await Task.Delay(1);
|
|
WeakReferenceMessenger.Default.Send(new SignalRNewsCategoriesChangedMessage());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler wenn zu einer Konversation eine Nachricht hinzugefügt wurde
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <returns></returns>
|
|
private async Task ConversationMessageAddedAsync(MessageDto message)
|
|
{
|
|
await Task.Delay(1);
|
|
WeakReferenceMessenger.Default.Send(new SignalRConversationMessageAddedMessage(message.ConversationId));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler wenn neue Nachrichten für einen Benutzer da sind
|
|
/// </summary>
|
|
/// <returns>Task</returns>
|
|
private async Task MessageAddedAsync()
|
|
{
|
|
await Task.Delay(1);
|
|
WeakReferenceMessenger.Default.Send(new MessagesChangedMessage());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler wenn neue SystemNachrichten für einen Benutzer da sind
|
|
/// </summary>
|
|
/// <returns>Task</returns>
|
|
private async Task SystemMessageAddedAsync()
|
|
{
|
|
await Task.Delay(1);
|
|
WeakReferenceMessenger.Default.Send(new SignalRSystemMessagesChangedMessage());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler wenn der Benutzer abgemeldet werden soll
|
|
/// </summary>
|
|
/// <returns>Task</returns>
|
|
private async Task LogoutAsync()
|
|
{
|
|
await Task.Delay(1);
|
|
WeakReferenceMessenger.Default.Send(new LogoutMessage());
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|