@@ -8,67 +8,68 @@ using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Server;
|
||||
using Wino.Messaging;
|
||||
|
||||
namespace Wino.Server.Core;
|
||||
|
||||
public abstract class ServerMessageHandlerBase
|
||||
namespace Wino.Server.Core
|
||||
{
|
||||
public string HandlingRequestType { get; }
|
||||
|
||||
public abstract Task ExecuteAsync(IClientMessage message, AppServiceRequest request = null, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
public abstract class ServerMessageHandler<TClientMessage, TResponse> : ServerMessageHandlerBase where TClientMessage : IClientMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Response to return when server encounters and exception while executing code.
|
||||
/// </summary>
|
||||
/// <param name="ex">Exception that target threw.</param>
|
||||
/// <returns>Default response on failure object.</returns>
|
||||
public abstract WinoServerResponse<TResponse> FailureDefaultResponse(Exception ex);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Safely executes the handler code and returns the response.
|
||||
/// This call will never crash the server. Exceptions encountered will be handled and returned as response.
|
||||
/// </summary>
|
||||
/// <param name="message">IClientMessage that client asked the response for from the server.</param>
|
||||
/// <param name="request">optional AppServiceRequest to return response for.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Response object that server executes for the given method.</returns>
|
||||
public override async Task ExecuteAsync(IClientMessage message, AppServiceRequest request = null, CancellationToken cancellationToken = default)
|
||||
public abstract class ServerMessageHandlerBase
|
||||
{
|
||||
WinoServerResponse<TResponse> response = default;
|
||||
public string HandlingRequestType { get; }
|
||||
|
||||
try
|
||||
{
|
||||
response = await HandleAsync((TClientMessage)message, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
response = FailureDefaultResponse(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// No need to send response if request is null.
|
||||
// Handler might've been called directly from the server itself.
|
||||
if (request != null)
|
||||
{
|
||||
var valueSet = new ValueSet()
|
||||
{
|
||||
{ MessageConstants.MessageDataKey, JsonSerializer.Serialize(response) }
|
||||
};
|
||||
|
||||
await request.SendResponseAsync(valueSet);
|
||||
}
|
||||
}
|
||||
public abstract Task ExecuteAsync(IClientMessage message, AppServiceRequest request = null, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Code that will be executed directly on the server.
|
||||
/// All handlers must implement this method.
|
||||
/// Response is wrapped with WinoServerResponse.
|
||||
/// </summary>
|
||||
/// <param name="message">IClientMessage that client asked the response for from the server.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
protected abstract Task<WinoServerResponse<TResponse>> HandleAsync(TClientMessage message, CancellationToken cancellationToken = default);
|
||||
public abstract class ServerMessageHandler<TClientMessage, TResponse> : ServerMessageHandlerBase where TClientMessage : IClientMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Response to return when server encounters and exception while executing code.
|
||||
/// </summary>
|
||||
/// <param name="ex">Exception that target threw.</param>
|
||||
/// <returns>Default response on failure object.</returns>
|
||||
public abstract WinoServerResponse<TResponse> FailureDefaultResponse(Exception ex);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Safely executes the handler code and returns the response.
|
||||
/// This call will never crash the server. Exceptions encountered will be handled and returned as response.
|
||||
/// </summary>
|
||||
/// <param name="message">IClientMessage that client asked the response for from the server.</param>
|
||||
/// <param name="request">optional AppServiceRequest to return response for.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Response object that server executes for the given method.</returns>
|
||||
public override async Task ExecuteAsync(IClientMessage message, AppServiceRequest request = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
WinoServerResponse<TResponse> response = default;
|
||||
|
||||
try
|
||||
{
|
||||
response = await HandleAsync((TClientMessage)message, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
response = FailureDefaultResponse(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// No need to send response if request is null.
|
||||
// Handler might've been called directly from the server itself.
|
||||
if (request != null)
|
||||
{
|
||||
var valueSet = new ValueSet()
|
||||
{
|
||||
{ MessageConstants.MessageDataKey, JsonSerializer.Serialize(response) }
|
||||
};
|
||||
|
||||
await request.SendResponseAsync(valueSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Code that will be executed directly on the server.
|
||||
/// All handlers must implement this method.
|
||||
/// Response is wrapped with WinoServerResponse.
|
||||
/// </summary>
|
||||
/// <param name="message">IClientMessage that client asked the response for from the server.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
protected abstract Task<WinoServerResponse<TResponse>> HandleAsync(TClientMessage message, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,41 +5,42 @@ using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Messaging.Server;
|
||||
using Wino.Server.MessageHandlers;
|
||||
|
||||
namespace Wino.Server.Core;
|
||||
|
||||
public class ServerMessageHandlerFactory : IServerMessageHandlerFactory
|
||||
namespace Wino.Server.Core
|
||||
{
|
||||
public ServerMessageHandlerBase GetHandler(string typeName)
|
||||
public class ServerMessageHandlerFactory : IServerMessageHandlerFactory
|
||||
{
|
||||
return typeName switch
|
||||
public ServerMessageHandlerBase GetHandler(string typeName)
|
||||
{
|
||||
nameof(NewMailSynchronizationRequested) => App.Current.Services.GetService<MailSynchronizationRequestHandler>(),
|
||||
nameof(NewCalendarSynchronizationRequested) => App.Current.Services.GetService<CalendarSynchronizationRequestHandler>(),
|
||||
nameof(ServerRequestPackage) => App.Current.Services.GetService<UserActionRequestHandler>(),
|
||||
nameof(DownloadMissingMessageRequested) => App.Current.Services.GetService<SingleMimeDownloadHandler>(),
|
||||
nameof(AuthorizationRequested) => App.Current.Services.GetService<AuthenticationHandler>(),
|
||||
nameof(SynchronizationExistenceCheckRequest) => App.Current.Services.GetService<SyncExistenceHandler>(),
|
||||
nameof(ServerTerminationModeChanged) => App.Current.Services.GetService<ServerTerminationModeHandler>(),
|
||||
nameof(TerminateServerRequested) => App.Current.Services.GetService<TerminateServerRequestHandler>(),
|
||||
nameof(ImapConnectivityTestRequested) => App.Current.Services.GetService<ImapConnectivityTestHandler>(),
|
||||
nameof(KillAccountSynchronizerRequested) => App.Current.Services.GetService<KillAccountSynchronizerHandler>(),
|
||||
_ => throw new Exception($"Server handler for {typeName} is not registered."),
|
||||
};
|
||||
}
|
||||
return typeName switch
|
||||
{
|
||||
nameof(NewMailSynchronizationRequested) => App.Current.Services.GetService<MailSynchronizationRequestHandler>(),
|
||||
nameof(NewCalendarSynchronizationRequested) => App.Current.Services.GetService<CalendarSynchronizationRequestHandler>(),
|
||||
nameof(ServerRequestPackage) => App.Current.Services.GetService<UserActionRequestHandler>(),
|
||||
nameof(DownloadMissingMessageRequested) => App.Current.Services.GetService<SingleMimeDownloadHandler>(),
|
||||
nameof(AuthorizationRequested) => App.Current.Services.GetService<AuthenticationHandler>(),
|
||||
nameof(SynchronizationExistenceCheckRequest) => App.Current.Services.GetService<SyncExistenceHandler>(),
|
||||
nameof(ServerTerminationModeChanged) => App.Current.Services.GetService<ServerTerminationModeHandler>(),
|
||||
nameof(TerminateServerRequested) => App.Current.Services.GetService<TerminateServerRequestHandler>(),
|
||||
nameof(ImapConnectivityTestRequested) => App.Current.Services.GetService<ImapConnectivityTestHandler>(),
|
||||
nameof(KillAccountSynchronizerRequested) => App.Current.Services.GetService<KillAccountSynchronizerHandler>(),
|
||||
_ => throw new Exception($"Server handler for {typeName} is not registered."),
|
||||
};
|
||||
}
|
||||
|
||||
public void Setup(IServiceCollection serviceCollection)
|
||||
{
|
||||
// Register all known handlers.
|
||||
public void Setup(IServiceCollection serviceCollection)
|
||||
{
|
||||
// Register all known handlers.
|
||||
|
||||
serviceCollection.AddTransient<MailSynchronizationRequestHandler>();
|
||||
serviceCollection.AddTransient<CalendarSynchronizationRequestHandler>();
|
||||
serviceCollection.AddTransient<UserActionRequestHandler>();
|
||||
serviceCollection.AddTransient<SingleMimeDownloadHandler>();
|
||||
serviceCollection.AddTransient<AuthenticationHandler>();
|
||||
serviceCollection.AddTransient<SyncExistenceHandler>();
|
||||
serviceCollection.AddTransient<ServerTerminationModeHandler>();
|
||||
serviceCollection.AddTransient<TerminateServerRequestHandler>();
|
||||
serviceCollection.AddTransient<ImapConnectivityTestHandler>();
|
||||
serviceCollection.AddTransient<KillAccountSynchronizerHandler>();
|
||||
serviceCollection.AddTransient<MailSynchronizationRequestHandler>();
|
||||
serviceCollection.AddTransient<CalendarSynchronizationRequestHandler>();
|
||||
serviceCollection.AddTransient<UserActionRequestHandler>();
|
||||
serviceCollection.AddTransient<SingleMimeDownloadHandler>();
|
||||
serviceCollection.AddTransient<AuthenticationHandler>();
|
||||
serviceCollection.AddTransient<SyncExistenceHandler>();
|
||||
serviceCollection.AddTransient<ServerTerminationModeHandler>();
|
||||
serviceCollection.AddTransient<TerminateServerRequestHandler>();
|
||||
serviceCollection.AddTransient<ImapConnectivityTestHandler>();
|
||||
serviceCollection.AddTransient<KillAccountSynchronizerHandler>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user