извлекатель команд

This commit is contained in:
2025-02-17 16:52:58 +03:00
parent 327822d48c
commit abd83d0fda
20 changed files with 305 additions and 161 deletions
+4 -4
View File
@@ -1,12 +1,12 @@
namespace mROA.Abstract;
public delegate void ConnectionHandler(INextGenerationInteractionModule interactionModule);
public delegate void DisconnectionHandler(INextGenerationInteractionModule interactionModule);
public delegate void ConnectionHandler(IRepresentationModule representationModule);
public delegate void DisconnectionHandler(IRepresentationModule representationModule);
public interface IConnectionHub
{
void RegisterInteracion(INextGenerationInteractionModule interaction);
void RegisterInteraction(INextGenerationInteractionModule interaction);
INextGenerationInteractionModule GetInteracion(int id);
event ConnectionHandler? OnConnectied;
event ConnectionHandler? OnConnected;
event DisconnectionHandler? OnDisconnected;
}
@@ -0,0 +1,6 @@
namespace mROA.Abstract;
public interface IRepresentationModuleProducer : IInjectableModule
{
IRepresentationModule Produce(int id);
}
+6
View File
@@ -0,0 +1,6 @@
namespace mROA.Abstract;
public interface IRequestExtractor : IInjectableModule
{
Task StartExtraction();
}
+2 -1
View File
@@ -20,7 +20,8 @@ public interface ISerialisationModule : IInjectableModule
public interface IRepresentationModule : IInjectableModule
{
int Id { get; }
Task<T> GetMessage<T>(Guid? requestId, MessageType? messageType);
Task<T> GetMessage<T>(Guid? requestId = null, MessageType? messageType = null);
Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null);
Task PostCallMessage<T>(Guid id, MessageType messageType, T payload);
Task PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType);
}
@@ -1,8 +0,0 @@
using mROA.Abstract;
namespace mROA.Implementation;
interface ISerialisationModuleProducer : IInjectableModule
{
ISerialisationModule.IFrontendSerialisationModule Produce(int ownership);
}
+11 -6
View File
@@ -1,9 +1,14 @@
namespace mROA.Implementation;
using mROA.Abstract;
public interface ISerializationToolkit
namespace mROA.Implementation;
public interface ISerializationToolkit : IInjectableModule
{
public byte[] Serialize<T>(T objectToSerialize);
public byte[] Serialize(object objectToSerialize, Type type);
public T? Deserialize<T>(byte[] rawData);
public object? Deserialize(byte[] rawData, Type type);
byte[] Serialize<T>(T objectToSerialize);
byte[] Serialize(object objectToSerialize, Type type);
T? Deserialize<T>(byte[] rawData);
object? Deserialize(byte[] rawData, Type type);
T Cast<T>(object nonCasted);
object Cast(object nonCasted, Type type);
}
@@ -9,17 +9,12 @@ public static class BasicConfigurationExtensions
{
public static void UseJsonSerialisation(this FullMixBuilder builder)
{
builder.Modules.Add(new JsonSerialisationModule());
builder.Modules.Add(new JsonSerializationToolkit());
}
public static void UseNetworkGateway(this FullMixBuilder builder, IPEndPoint endPoint)
public static void UseNetworkGateway(this FullMixBuilder builder, IPEndPoint endPoint, Type interactionModuleType, params IInjectableModule[] injectableModules)
{
builder.Modules.Add(new NetworkGatewayModule(endPoint));
}
public static void UseStreamInteraction(this FullMixBuilder builder)
{
builder.Modules.Add(new StreamBasedInteractionModule());
builder.Modules.Add(new NetworkGatewayModule(endPoint, interactionModuleType, injectableModules));
}
public static void UseBasicExecution(this FullMixBuilder builder)
+11 -6
View File
@@ -4,18 +4,23 @@ namespace mROA.Implementation.Backend;
public class ConntectionHub : IConnectionHub
{
private Dictionary<int, INextGenerationInteractionModule> _connections = new();
public void RegisterInteracion(INextGenerationInteractionModule interaction)
private readonly Dictionary<int, INextGenerationInteractionModule> _connections = new();
private ISerializationToolkit _serializationToolkit;
public void RegisterInteraction(INextGenerationInteractionModule interaction)
{
OnConnectied?.Invoke(interaction);
var module = new RepresentationModule();
module.Inject(_serializationToolkit);
module.Inject(interaction);
OnConnected?.Invoke(module);
}
public INextGenerationInteractionModule GetInteracion(int id)
{
return _connections!.GetValueOrDefault(id, null) ?? throw new Exception("No connection found");
}
public event ConnectionHandler? OnConnectied;
public event ConnectionHandler? OnConnected;
public event DisconnectionHandler? OnDisconnected;
}
@@ -0,0 +1,39 @@
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class HubRequestExtractor : IInjectableModule
{
private IExecuteModule _executeModule;
private IConnectionHub _hub;
public void Inject<T>(T dependency)
{
switch (dependency)
{
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IConnectionHub connectionHub:
_hub = connectionHub;
_hub.OnConnected += HubOnOnConnected;
break;
}
}
private async void HubOnOnConnected(IRepresentationModule interaction)
{
try
{
while (true)
{
var messageReceiving = await interaction.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
}
}
catch (Exception e)
{
}
}
}
@@ -1,80 +1,80 @@
using System.Text;
using System.Text.Json;
using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class JsonSerialisationModule : ISerialisationModule
{
private IInteractionModule? _dataSource;
private IExecuteModule? _executeModule;
private IMethodRepository? _methodRepository;
private IContextRepository? _contextRepo;
public void HandleIncomingRequest(int clientId, byte[] message)
{
MultiClientOwnershipRepository? ownership = null;
if (TransmissionConfig.OwnershipRepository is MultiClientOwnershipRepository)
{
ownership = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
ownership.RegisterOwnership(clientId);
}
NetworkMessage input = JsonSerializer.Deserialize<NetworkMessage>(message)!;
Console.WriteLine(Encoding.Default.GetString(input.Data));
if (input.SchemaId == MessageType.CallRequest)
{
var command = JsonSerializer.Deserialize<DefaultCallRequest>(input.Data)!;
if (command.Parameter is not null)
{
var parameter = _methodRepository!.GetMethod(command.CommandId).GetParameters().First().ParameterType;
var jsElement = (JsonElement)command.Parameter;
command.Parameter = jsElement.Deserialize(parameter);
}
var response = _executeModule!.Execute(command, _contextRepo);
response.ClientId = clientId;
var resultType = response is FinalCommandExecution
? MessageType.FinishedCommandExecution
: MessageType.ErrorCommandExecution;
PostResponse(
new NetworkMessage
{
SchemaId = resultType,
Id = command.CallRequestId,
Data = JsonSerializer.SerializeToUtf8Bytes(response, response.GetType())
}, clientId);
}
ownership?.FreeOwnership();
}
public void PostResponse(NetworkMessage message, int clientId)
{
_dataSource!.SendTo(clientId, JsonSerializer.SerializeToUtf8Bytes(message));
}
public void SendWelcomeMessage(int clientId)
{
_dataSource!.SendTo(clientId, JsonSerializer.SerializeToUtf8Bytes(new NetworkMessage { Data = JsonSerializer.SerializeToUtf8Bytes(new IdAssingnment { Id = clientId }), SchemaId = MessageType.IdAssigning}));
}
public void Inject<T>(T dependency)
{
switch (dependency)
{
case IInteractionModule interactionModule:
_dataSource = interactionModule;
break;
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IContextRepository contextRepository:
_contextRepo = contextRepository;
break;
}
}
}
// using System.Text;
// using System.Text.Json;
// using mROA.Abstract;
//
// namespace mROA.Implementation.Backend;
//
// public class JsonSerialisationModule : ISerialisationModule
// {
// private IInteractionModule? _dataSource;
// private IExecuteModule? _executeModule;
// private IMethodRepository? _methodRepository;
// private IContextRepository? _contextRepo;
//
// public void HandleIncomingRequest(int clientId, byte[] message)
// {
// MultiClientOwnershipRepository? ownership = null;
// if (TransmissionConfig.OwnershipRepository is MultiClientOwnershipRepository)
// {
// ownership = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
// ownership.RegisterOwnership(clientId);
// }
//
// NetworkMessage input = JsonSerializer.Deserialize<NetworkMessage>(message)!;
// Console.WriteLine(Encoding.Default.GetString(input.Data));
// if (input.SchemaId == MessageType.CallRequest)
// {
// var command = JsonSerializer.Deserialize<DefaultCallRequest>(input.Data)!;
// if (command.Parameter is not null)
// {
// var parameter = _methodRepository!.GetMethod(command.CommandId).GetParameters().First().ParameterType;
// var jsElement = (JsonElement)command.Parameter;
// command.Parameter = jsElement.Deserialize(parameter);
// }
//
// var response = _executeModule!.Execute(command, _contextRepo);
// response.ClientId = clientId;
// var resultType = response is FinalCommandExecution
// ? MessageType.FinishedCommandExecution
// : MessageType.ErrorCommandExecution;
// PostResponse(
// new NetworkMessage
// {
// SchemaId = resultType,
// Id = command.CallRequestId,
// Data = JsonSerializer.SerializeToUtf8Bytes(response, response.GetType())
// }, clientId);
// }
//
// ownership?.FreeOwnership();
// }
//
// public void PostResponse(NetworkMessage message, int clientId)
// {
// _dataSource!.SendTo(clientId, JsonSerializer.SerializeToUtf8Bytes(message));
// }
//
// public void SendWelcomeMessage(int clientId)
// {
// _dataSource!.SendTo(clientId, JsonSerializer.SerializeToUtf8Bytes(new NetworkMessage { Data = JsonSerializer.SerializeToUtf8Bytes(new IdAssingnment { Id = clientId }), SchemaId = MessageType.IdAssigning}));
// }
//
// public void Inject<T>(T dependency)
// {
// switch (dependency)
// {
// case IInteractionModule interactionModule:
// _dataSource = interactionModule;
// break;
// case IExecuteModule executeModule:
// _executeModule = executeModule;
// break;
// case IMethodRepository methodRepository:
// _methodRepository = methodRepository;
// break;
// case IContextRepository contextRepository:
// _contextRepo = contextRepository;
// break;
// }
// }
// }
@@ -4,7 +4,7 @@ using mROA.Abstract;
namespace mROA.Implementation.Backend;
public class NetworkGatewayModule() : IGatewayModule
public class NetworkGatewayModule : IGatewayModule
{
private readonly IPEndPoint? _endpoint;
private readonly Type? _interactionModuleType;
@@ -64,9 +64,10 @@ public class NetworkGatewayModule() : IGatewayModule
var client = _tcpListener.AcceptTcpClient();
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
var interacton = Activator.CreateInstance(_interactionModuleType) as INextGenerationInteractionModule;
foreach (var injectableModule in _injectableModules)
interacton.Inject(injectableModule);
_hub.RegisterInteracion(new NextGenerationInteractionModule());
_hub.RegisterInteraction(interacton);
Console.WriteLine("Client registered");
}
}
+3 -1
View File
@@ -13,5 +13,7 @@ public class DefaultCallRequest : ICallRequest
public Guid CallRequestId { get; set; } = Guid.NewGuid();
public int CommandId { get; init; }
public int ObjectId { get; init; } = -1;
public Type ParameterType { get; init; }
public object? Parameter { get; set; }
}
}
@@ -4,43 +4,39 @@ using mROA.Implementation.Frontend;
namespace mROA.Implementation;
public class CreativeSerializationModuleProducer : ISerialisationModuleProducer
public class CreativeSerializationModuleProducer : IRepresentationModuleProducer
{
private Type _serializationModuleType;
private Type _reprModuleType;
private IInjectableModule[] _creationModules;
private StreamBasedInteractionModule? _interactionModule;
private IConnectionHub? _hub;
public CreativeSerializationModuleProducer(IInjectableModule[] creationModules, Type serializationModuleType)а
public CreativeSerializationModuleProducer(IInjectableModule[] creationModules, Type reprModuleType)
{
_creationModules = creationModules;
_serializationModuleType = serializationModuleType;
_reprModuleType = reprModuleType;
}
public void Inject<T>(T dependency)
{
if (dependency is StreamBasedInteractionModule interactionModule)
_interactionModule = interactionModule;
if (dependency is IConnectionHub interactionModule)
_hub = interactionModule;
}
public ISerialisationModule.IFrontendSerialisationModule Produce(int ownership)
public IRepresentationModule Produce(int id)
{
if (_interactionModule == null)
if (_hub == null)
throw new NullReferenceException("Interaction module is null");
var produced =
Activator.CreateInstance(_serializationModuleType) as ISerialisationModule.IFrontendSerialisationModule ??
Activator.CreateInstance(_reprModuleType) as IRepresentationModule ??
throw new Exception("Bad serialization module type");
foreach (var creationModule in _creationModules)
produced.Inject(creationModule);
var interactionModule = new StreamBasedFrontendInteractionModule
{
ClientId = ownership,
ServerStream = _interactionModule.GetSource(ownership)
};
produced.Inject(interactionModule);
produced.Inject(_hub.GetInteracion(id));
return produced;
}
}
@@ -0,0 +1,67 @@
using mROA.Abstract;
namespace mROA.Implementation.Frontend;
public class RequestExtractor : IRequestExtractor
{
private IRepresentationModule? _representationModule;
private IContextRepository? _contextRepository;
private IMethodRepository? _methodRepository;
private IExecuteModule? _executeModule;
private ISerializationToolkit? _serializationToolkit;
public void Inject<T>(T dependency)
{
switch (dependency)
{
case IExecuteModule executeModule:
_executeModule = executeModule;
break;
case IContextRepository contextRepository:
_contextRepository = contextRepository;
break;
case IMethodRepository methodRepository:
_methodRepository = methodRepository;
break;
case IRepresentationModule representationModule:
_representationModule = representationModule;
break;
case ISerializationToolkit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
}
}
public async Task StartExtraction()
{
if (_serializationToolkit == null)
throw new NullReferenceException("Serializing toolkit is null.");
if (_executeModule == null)
throw new NullReferenceException("Execute module is null.");
if (_contextRepository == null)
throw new NullReferenceException("Context repository is null.");
if (_representationModule == null)
throw new NullReferenceException("Representation module is null.");
if (_methodRepository == null)
throw new NullReferenceException("Method repository is null.");
while (true)
{
var request = await _representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
if (request.Parameter is not null)
{
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First().ParameterType;
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
}
var result = _executeModule.Execute(request, _contextRepository);
var resultType = result is FinalCommandExecution
? MessageType.FinishedCommandExecution
: MessageType.ErrorCommandExecution;
await _representationModule.PostCallMessage(request.CallRequestId, resultType, result);
}
}
}
@@ -23,4 +23,26 @@ public class JsonSerializationToolkit : ISerializationToolkit
{
return JsonSerializer.Deserialize(rawData, type);
}
public T Cast<T>(object nonCasted)
{
if (nonCasted is JsonElement jsonElement)
return jsonElement.Deserialize<T>()!;
if (nonCasted is T casted)
return casted;
throw new JsonException("Cannot cast object to type " + typeof(T).FullName);
}
public object Cast(object nonCasted, Type type)
{
if (nonCasted is JsonElement jsonElement)
return jsonElement.Deserialize(type)!;
throw new JsonException("Cannot cast object to type " + type.FullName);
}
public void Inject<T>(T dependency)
{
}
}
@@ -5,7 +5,7 @@ namespace mROA.Implementation;
public class RemoteContextRepository : IContextRepository
{
private ISerialisationModuleProducer _serialisationProducer;
private IRepresentationModuleProducer _representationProducer;
public static FrozenDictionary<Type, Type> RemoteTypes;
public int ResisterObject(object o)
{
@@ -26,7 +26,7 @@ public class RemoteContextRepository : IContextRepository
{
if (RemoteTypes.TryGetValue(typeof(T), out var remoteType))
{
var remote = (T)Activator.CreateInstance(remoteType, id, _serialisationProducer.Produce(TransmissionConfig.OwnershipRepository!.GetOwnershipId()))!;
var remote = (T)Activator.CreateInstance(remoteType, id, _representationProducer.Produce(TransmissionConfig.OwnershipRepository!.GetOwnershipId()))!;
return remote;
}
throw new NotSupportedException();
@@ -34,7 +34,7 @@ public class RemoteContextRepository : IContextRepository
public object GetSingleObject(Type type)
{
return Activator.CreateInstance(RemoteTypes[type], -1, _serialisationProducer.Produce(TransmissionConfig.OwnershipRepository.GetOwnershipId()))!;
return Activator.CreateInstance(RemoteTypes[type], -1, _representationProducer.Produce(TransmissionConfig.OwnershipRepository.GetOwnershipId()))!;
}
public int GetObjectIndex(object o)
@@ -48,7 +48,7 @@ public class RemoteContextRepository : IContextRepository
public void Inject<T>(T dependency)
{
if (dependency is ISerialisationModuleProducer serialisationModule)
_serialisationProducer = serialisationModule;
if (dependency is IRepresentationModuleProducer serialisationModule)
_representationProducer = serialisationModule;
}
}
+10 -3
View File
@@ -23,12 +23,18 @@ public class RepresentationModule : IRepresentationModule
public int Id { get; set; }
public async Task<T> GetMessage<T>(Guid? requestId, MessageType? messageType)
{
return _serialization.Deserialize<T>(await GetRawMessage(requestId, messageType))!;
}
public async Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null)
{
while (true)
{
var message = await _interaction.GetNextMessageReceiving();
if ((requestId is null || message.Id == requestId) && (messageType is null || message.SchemaId == messageType))
return _serialization.Deserialize<T>(message.Data)!;
if ((requestId is null || message.Id == requestId) &&
(messageType is null || message.SchemaId == messageType))
return message.Data;
}
}
@@ -39,6 +45,7 @@ public class RepresentationModule : IRepresentationModule
public async Task PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType)
{
await _interaction.PostMessage(new NetworkMessage {Id = id, SchemaId = messageType, Data = _serialization.Serialize(payload, payloadType)});
await _interaction.PostMessage(new NetworkMessage
{ Id = id, SchemaId = messageType, Data = _serialization.Serialize(payload, payloadType) });
}
}
@@ -0,0 +1,19 @@
using mROA.Abstract;
namespace mROA.Implementation;
public class StaticRepresentationModuleProducer : IRepresentationModuleProducer
{
private IRepresentationModule _reprModule;
public IRepresentationModule Produce(int ownership)
{
return _reprModule;
}
public void Inject<T>(T dependency)
{
if (dependency is IRepresentationModule serialisationModule)
_reprModule = serialisationModule;
}
}
@@ -1,19 +0,0 @@
using mROA.Abstract;
namespace mROA.Implementation;
public class StaticSerialisationModuleProducer : ISerialisationModuleProducer
{
private ISerialisationModule.IFrontendSerialisationModule _serialisationModule;
public ISerialisationModule.IFrontendSerialisationModule Produce(int ownership)
{
return _serialisationModule;
}
public void Inject<T>(T dependency)
{
if (dependency is ISerialisationModule.IFrontendSerialisationModule serialisationModule)
_serialisationModule = serialisationModule;
}
}