кодовая база для нового базового класса удаленного объекта

This commit is contained in:
2025-02-17 23:19:54 +03:00
parent 4ab508e54f
commit 7897557dbc
12 changed files with 118 additions and 43 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ namespace mROA.Abstract;
public interface ICommandExecution public interface ICommandExecution
{ {
Guid CallRequestId { get; init; } Guid Id { get; init; }
int ClientId { get; set; } int ClientId { get; set; }
int CommandId { get; } int CommandId { get; }
} }
-7
View File
@@ -1,7 +0,0 @@
namespace mROA.Abstract;
public interface IRemoteObject
{
public int Id { get; }
public int OwnerId { get; }
}
@@ -48,7 +48,7 @@ public class BasicExecutionModule : IExecuteModule
return new TypedFinalCommandExecution return new TypedFinalCommandExecution
{ {
CommandId = command.CommandId, Result = finalResult, CommandId = command.CommandId, Result = finalResult,
CallRequestId = command.CallRequestId, Id = command.CallRequestId,
Type = currentCommand.ReturnType Type = currentCommand.ReturnType
}; };
} }
@@ -56,7 +56,7 @@ public class BasicExecutionModule : IExecuteModule
{ {
return new ExceptionCommandExecution return new ExceptionCommandExecution
{ {
CallRequestId = command.CallRequestId, CommandId = command.CommandId, Id = command.CallRequestId, CommandId = command.CommandId,
Exception = e.ToString() Exception = e.ToString()
}; };
} }
@@ -75,13 +75,13 @@ public class BasicExecutionModule : IExecuteModule
result.Wait(token); result.Wait(token);
return new FinalCommandExecution { CommandId = command.CommandId, CallRequestId = command.CallRequestId }; return new FinalCommandExecution { CommandId = command.CommandId, Id = command.CallRequestId };
} }
catch (Exception e) catch (Exception e)
{ {
return new ExceptionCommandExecution return new ExceptionCommandExecution
{ {
CallRequestId = command.CallRequestId, CommandId = command.CommandId, Id = command.CallRequestId, CommandId = command.CommandId,
Exception = e.ToString() Exception = e.ToString()
}; };
} }
@@ -102,7 +102,7 @@ public class BasicExecutionModule : IExecuteModule
var finalResult = result.GetType().GetProperty("Result")?.GetValue(result); var finalResult = result.GetType().GetProperty("Result")?.GetValue(result);
return new TypedFinalCommandExecution return new TypedFinalCommandExecution
{ {
CallRequestId = command.CallRequestId, Id = command.CallRequestId,
Result = finalResult, Result = finalResult,
CommandId = command.CommandId, CommandId = command.CommandId,
Type = finalResult?.GetType() Type = finalResult?.GetType()
@@ -112,7 +112,7 @@ public class BasicExecutionModule : IExecuteModule
{ {
return new ExceptionCommandExecution return new ExceptionCommandExecution
{ {
CallRequestId = command.CallRequestId, CommandId = command.CommandId, Id = command.CallRequestId, CommandId = command.CommandId,
Exception = e.ToString() Exception = e.ToString()
}; };
} }
@@ -6,7 +6,6 @@ namespace mROA.Implementation.Backend;
public class NetworkGatewayModule : IGatewayModule public class NetworkGatewayModule : IGatewayModule
{ {
private readonly IPEndPoint? _endpoint;
private readonly Type? _interactionModuleType; private readonly Type? _interactionModuleType;
private readonly IInjectableModule[]? _injectableModules; private readonly IInjectableModule[]? _injectableModules;
private readonly TcpListener? _tcpListener; private readonly TcpListener? _tcpListener;
@@ -14,16 +13,14 @@ public class NetworkGatewayModule : IGatewayModule
public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, IInjectableModule[] injectableModules) public NetworkGatewayModule(IPEndPoint endpoint, Type interactionModuleType, IInjectableModule[] injectableModules)
{ {
_endpoint = endpoint; _tcpListener = new(endpoint);
_tcpListener = new(_endpoint);
_interactionModuleType = interactionModuleType; _interactionModuleType = interactionModuleType;
_injectableModules = injectableModules; _injectableModules = injectableModules;
} }
public void Run() public void Run()
{ {
_tcpListener.Start(); _tcpListener!.Start();
Console.WriteLine($"Listening on {_tcpListener.LocalEndpoint}"); Console.WriteLine($"Listening on {_tcpListener.LocalEndpoint}");
Console.WriteLine("Enter Backspace to stop"); Console.WriteLine("Enter Backspace to stop");
+5 -2
View File
@@ -1,4 +1,6 @@
namespace mROA.Implementation; using System.Text.Json.Serialization;
namespace mROA.Implementation;
public interface ICallRequest public interface ICallRequest
{ {
@@ -14,6 +16,7 @@ public class DefaultCallRequest : ICallRequest
public int CommandId { get; init; } public int CommandId { get; init; }
public int ObjectId { get; init; } = -1; public int ObjectId { get; init; } = -1;
public Type ParameterType { get; init; } [JsonIgnore]
public Type? ParameterType { get; init; }
public object? Parameter { get; set; } public object? Parameter { get; set; }
} }
@@ -1,11 +1,18 @@
using mROA.Abstract; using System.Text.Json;
using mROA.Abstract;
using mROA.Implementation.Frontend;
namespace mROA.Implementation; namespace mROA.Implementation;
public class ExceptionCommandExecution : ICommandExecution public class ExceptionCommandExecution : ICommandExecution
{ {
public Guid CallRequestId { get; init; } public Guid Id { get; init; }
public int ClientId { get; set; } public int ClientId { get; set; }
public int CommandId { get; init; } public int CommandId { get; init; }
public required string Exception { get; set; } public required string Exception { get; set; }
public RemoteException GetException()
{
return new RemoteException(Exception) { CallRequestId = Id };
}
} }
@@ -7,7 +7,7 @@ namespace mROA.Implementation;
public class FinalCommandExecution : ICommandExecution public class FinalCommandExecution : ICommandExecution
{ {
public Guid CallRequestId { get; init; } public Guid Id { get; init; }
[JsonIgnore] [JsonIgnore]
public int ClientId { get; set; } public int ClientId { get; set; }
[JsonIgnore] [JsonIgnore]
@@ -1,4 +1,5 @@
using mROA.Abstract; using mROA.Abstract;
using mROA.Implementation.Backend;
namespace mROA.Implementation.Frontend; namespace mROA.Implementation.Frontend;
@@ -9,6 +10,7 @@ public class RequestExtractor : IRequestExtractor
private IMethodRepository? _methodRepository; private IMethodRepository? _methodRepository;
private IExecuteModule? _executeModule; private IExecuteModule? _executeModule;
private ISerializationToolkit? _serializationToolkit; private ISerializationToolkit? _serializationToolkit;
public void Inject<T>(T dependency) public void Inject<T>(T dependency)
{ {
switch (dependency) switch (dependency)
@@ -44,13 +46,23 @@ public class RequestExtractor : IRequestExtractor
if (_methodRepository == null) if (_methodRepository == null)
throw new NullReferenceException("Method repository is null."); throw new NullReferenceException("Method repository is null.");
var multiClientOwnershipRepository = TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
try
{
while (true) while (true)
{ {
var request = await _representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest); var request =
await _representationModule!.GetMessage<DefaultCallRequest>(messageType: MessageType.CallRequest);
if (request.Parameter is not null) if (request.Parameter is not null)
{ {
var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First().ParameterType; var parameterType = _methodRepository!.GetMethod(request.CommandId).GetParameters().First()
.ParameterType;
request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType); request.Parameter = _serializationToolkit.Cast(request.Parameter, parameterType);
} }
@@ -58,10 +70,14 @@ public class RequestExtractor : IRequestExtractor
var resultType = result is FinalCommandExecution var resultType = result is FinalCommandExecution
? MessageType.FinishedCommandExecution ? MessageType.FinishedCommandExecution
: MessageType.ErrorCommandExecution; : MessageType.ExceptionCommandExecution;
await _representationModule.PostCallMessage(request.CallRequestId, resultType, result); await _representationModule.PostCallMessage(request.CallRequestId, resultType, result);
}
}
catch
{
multiClientOwnershipRepository?.RegisterOwnership(_representationModule.Id);
} }
} }
} }
+1 -1
View File
@@ -12,5 +12,5 @@ public class NetworkMessage
public enum MessageType public enum MessageType
{ {
Unknown, FinishedCommandExecution, ErrorCommandExecution, AcyncCancelCommandExecution, CallRequest, IdAssigning Unknown, FinishedCommandExecution, ExceptionCommandExecution, AcyncCancelCommandExecution, CallRequest, IdAssigning
} }
@@ -39,7 +39,7 @@ public class RemoteContextRepository : IContextRepository
public int GetObjectIndex(object o) public int GetObjectIndex(object o)
{ {
if (o is IRemoteObject remote) if (o is RemoteObjectBase remote)
{ {
return remote.Id; return remote.Id;
} }
+59
View File
@@ -0,0 +1,59 @@
using mROA.Implementation;
// ReSharper disable UnusedMember.Global
namespace mROA.Abstract;
public abstract class RemoteObjectBase
{
private readonly int _id;
private readonly IRepresentationModule _representationModule;
public int Id => _id;
public int OwnerId => _representationModule.Id;
public RemoteObjectBase(int id, IRepresentationModule representationModule)
{
_id = id;
_representationModule = representationModule;
}
public async Task<T> GetResultAsync<T>(int methodId, object? parameter = default)
{
var request = new DefaultCallRequest
{ CommandId = methodId, ObjectId = _id, Parameter = parameter, ParameterType = parameter?.GetType() };
await _representationModule.PostCallMessage(request.CallRequestId, MessageType.CallRequest, request);
var successResponse =
_representationModule.GetMessage<FinalCommandExecution<T>>(
messageType: MessageType.FinishedCommandExecution, requestId: request.CallRequestId);
var errorResponse =
_representationModule.GetMessage<ExceptionCommandExecution>(
messageType: MessageType.ExceptionCommandExecution, requestId: request.CallRequestId);
Task.WaitAny(successResponse, errorResponse);
if (successResponse.IsCompletedSuccessfully)
return successResponse.Result.Result!;
throw errorResponse.Result.GetException();
}
public async Task CallAsync(int methodId, object? parameter = default)
{
var request = new DefaultCallRequest
{ CommandId = methodId, ObjectId = _id, Parameter = parameter, ParameterType = parameter?.GetType() };
await _representationModule.PostCallMessage(request.CallRequestId, MessageType.CallRequest, request);
var successResponse =
_representationModule.GetMessage<FinalCommandExecution>(
messageType: MessageType.FinishedCommandExecution, requestId: request.CallRequestId);
var errorResponse =
_representationModule.GetMessage<ExceptionCommandExecution>(
messageType: MessageType.ExceptionCommandExecution, requestId: request.CallRequestId);
Task.WaitAny(successResponse, errorResponse);
if (successResponse.IsCompletedSuccessfully)
return;
throw errorResponse.Result.GetException();
}
}
+1 -1
View File
@@ -63,7 +63,7 @@ public class SharedObject<T> where T : notnull
{ {
Value = value; Value = value;
if (value is IRemoteObject ro) if (value is RemoteObjectBase ro)
{ {
_ownerId = ro.OwnerId; _ownerId = ro.OwnerId;
_contextId = ro.Id; _contextId = ro.Id;