From cd184b9060375e8b56ab72194f4e6a46a90f78b0 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Thu, 13 Feb 2025 10:52:06 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=BA=D0=B8=D0=B4=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B0=D0=B9=D0=B4=D0=B8=D1=88?= =?UTF-8?q?=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Example.Backend/Printer.cs | 2 +- Example.Backend/PrinterFactory.cs | 2 +- Example.Frontend/Program.cs | 5 +- Example.Shared/IPrinter.cs | 2 +- Example.Shared/IPrinterFactory.cs | 2 +- mROA/Abstract/ISerialisationModule.cs | 1 + .../Backend/JsonSerialisationModule.cs | 5 ++ .../Backend/StreamBasedInteractionModule.cs | 3 + ...JsonFrontendCallbackSerializationModule.cs | 5 ++ .../Frontend/NetworkFrontendBridge.cs | 10 +++ mROA/Implementation/IdAssingnment.cs | 6 ++ mROA/Implementation/MethodRepository.cs | 3 +- mROA/Implementation/NetworkMessage.cs | 2 +- mROA/Implementation/SharedObject.cs | 62 +++++++++++++++++++ .../Implementation/TransmittedSharedObject.cs | 49 --------------- 15 files changed, 102 insertions(+), 57 deletions(-) create mode 100644 mROA/Implementation/IdAssingnment.cs create mode 100644 mROA/Implementation/SharedObject.cs delete mode 100644 mROA/Implementation/TransmittedSharedObject.cs diff --git a/Example.Backend/Printer.cs b/Example.Backend/Printer.cs index 947005f..b456160 100644 --- a/Example.Backend/Printer.cs +++ b/Example.Backend/Printer.cs @@ -12,7 +12,7 @@ public class Printer : IPrinter return Name; } - public async Task> Print(string text, CancellationToken cancellationToken = default) + public async Task> Print(string text, CancellationToken cancellationToken = default) { // throw new Exception("The method or operation is not implemented."); return new Page {Text = text}; diff --git a/Example.Backend/PrinterFactory.cs b/Example.Backend/PrinterFactory.cs index bd376cc..99d8150 100644 --- a/Example.Backend/PrinterFactory.cs +++ b/Example.Backend/PrinterFactory.cs @@ -8,7 +8,7 @@ namespace Example.Backend; [SharedObjectSingleton] public class PrinterFactory : IPrinterFactory { - public TransmittedSharedObject Create(string printerName) + public SharedObject Create(string printerName) { return new Printer {Name = printerName}; } diff --git a/Example.Frontend/Program.cs b/Example.Frontend/Program.cs index 542c800..02b758f 100644 --- a/Example.Frontend/Program.cs +++ b/Example.Frontend/Program.cs @@ -19,9 +19,12 @@ mixer.Modules.Add(new StreamBasedFrontendInteractionModule()); mixer.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567))); mixer.Build(); -TransmissionConfig.RealContextRepository = mixer.GetModule(); +TransmissionConfig.RealContextRepository = mixer.GetModule(); +TransmissionConfig.RemoteEndpointContextRepository = mixer.GetModule(); mixer.GetModule().Connect(); + +Console.WriteLine(TransmissionConfig.ProcessOwnerId); var context = mixer.GetModule(); var factory = context.GetSingleObject(typeof(IPrinterFactory)) as IPrinterFactory; diff --git a/Example.Shared/IPrinter.cs b/Example.Shared/IPrinter.cs index b3fecbb..2d8e6c8 100644 --- a/Example.Shared/IPrinter.cs +++ b/Example.Shared/IPrinter.cs @@ -7,6 +7,6 @@ namespace Example.Shared; public interface IPrinter { string GetName(); - Task> Print(string text, CancellationToken cancellationToken); + Task> Print(string text, CancellationToken cancellationToken); } \ No newline at end of file diff --git a/Example.Shared/IPrinterFactory.cs b/Example.Shared/IPrinterFactory.cs index 6ea8b0c..73a4e93 100644 --- a/Example.Shared/IPrinterFactory.cs +++ b/Example.Shared/IPrinterFactory.cs @@ -7,6 +7,6 @@ namespace Example.Shared; [SharedObjectInterface] public interface IPrinterFactory { - TransmittedSharedObject Create(string printerName); + SharedObject Create(string printerName); } diff --git a/mROA/Abstract/ISerialisationModule.cs b/mROA/Abstract/ISerialisationModule.cs index b819ba5..fa3f26f 100644 --- a/mROA/Abstract/ISerialisationModule.cs +++ b/mROA/Abstract/ISerialisationModule.cs @@ -6,6 +6,7 @@ public interface ISerialisationModule : IInjectableModule { void HandleIncomingRequest(int clientId, byte[] message); void PostResponse(NetworkMessage message, int clientId); + void SendWelcomeMessage(int clientId); public interface IFrontendSerialisationModule : IInjectableModule { Task GetNextCommandExecution(Guid requestId) where T : ICommandExecution; diff --git a/mROA/Implementation/Backend/JsonSerialisationModule.cs b/mROA/Implementation/Backend/JsonSerialisationModule.cs index 9779539..511f42b 100644 --- a/mROA/Implementation/Backend/JsonSerialisationModule.cs +++ b/mROA/Implementation/Backend/JsonSerialisationModule.cs @@ -44,6 +44,11 @@ public class JsonSerialisationModule : ISerialisationModule _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 dependency) { if (dependency is IInteractionModule interactionModule) diff --git a/mROA/Implementation/Backend/StreamBasedInteractionModule.cs b/mROA/Implementation/Backend/StreamBasedInteractionModule.cs index 668cd23..faf3a11 100644 --- a/mROA/Implementation/Backend/StreamBasedInteractionModule.cs +++ b/mROA/Implementation/Backend/StreamBasedInteractionModule.cs @@ -4,6 +4,7 @@ namespace mROA.Implementation.Backend; public class StreamBasedInteractionModule : IInteractionModule { + private ISerialisationModule _serialisationModule; private readonly Dictionary _streams = new(); private Action? _handler; @@ -12,6 +13,7 @@ public class StreamBasedInteractionModule : IInteractionModule var id = Random.Shared.Next(); _streams.Add(id, stream); _ = ListenTo((id, stream), _handler!); + _serialisationModule.SendWelcomeMessage(id); } public void SendTo(int clientId, byte[] message) @@ -51,6 +53,7 @@ public class StreamBasedInteractionModule : IInteractionModule if (dependency is ISerialisationModule serialisationModule) { _handler = serialisationModule.HandleIncomingRequest; + _serialisationModule = serialisationModule; } } diff --git a/mROA/Implementation/Frontend/Callback/JsonFrontendCallbackSerializationModule.cs b/mROA/Implementation/Frontend/Callback/JsonFrontendCallbackSerializationModule.cs index 8a181b2..9759e20 100644 --- a/mROA/Implementation/Frontend/Callback/JsonFrontendCallbackSerializationModule.cs +++ b/mROA/Implementation/Frontend/Callback/JsonFrontendCallbackSerializationModule.cs @@ -21,4 +21,9 @@ public class JsonFrontendCallbackSerializationModule : ISerialisationModule { throw new NotImplementedException(); } + + public void SendWelcomeMessage(int clientId) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/mROA/Implementation/Frontend/NetworkFrontendBridge.cs b/mROA/Implementation/Frontend/NetworkFrontendBridge.cs index e5ce65f..a77c147 100644 --- a/mROA/Implementation/Frontend/NetworkFrontendBridge.cs +++ b/mROA/Implementation/Frontend/NetworkFrontendBridge.cs @@ -1,5 +1,7 @@ using System.Net; using System.Net.Sockets; +using System.Text; +using System.Text.Json; using mROA.Abstract; namespace mROA.Implementation.Frontend; @@ -24,5 +26,13 @@ public class NetworkFrontendBridge(IPEndPoint ipEndPoint) : IFrontendBridge _tcpClient.Connect(ipEndPoint); _interactionModule.ServerStream = _tcpClient.GetStream(); + var welcomeMessage = _interactionModule.ReceiveMessage().GetAwaiter().GetResult(); + var message = JsonSerializer.Deserialize(welcomeMessage); + if (message.SchemaId != MessageType.IdAssigning) + { + throw new Exception($"Incorrect message type. Must be IdAssigning, current : {message.SchemaId.ToString()}"); + } + + TransmissionConfig.ProcessOwnerId = JsonSerializer.Deserialize(message.Data)!.Id; } } \ No newline at end of file diff --git a/mROA/Implementation/IdAssingnment.cs b/mROA/Implementation/IdAssingnment.cs new file mode 100644 index 0000000..5cdb944 --- /dev/null +++ b/mROA/Implementation/IdAssingnment.cs @@ -0,0 +1,6 @@ +namespace mROA.Implementation; + +public class IdAssingnment +{ + public int Id { get; set; } +} \ No newline at end of file diff --git a/mROA/Implementation/MethodRepository.cs b/mROA/Implementation/MethodRepository.cs index 7a9a8bd..d429229 100644 --- a/mROA/Implementation/MethodRepository.cs +++ b/mROA/Implementation/MethodRepository.cs @@ -38,7 +38,6 @@ public class MethodRepository : IMethodRepository } public void Inject(T dependency) { + } - - } \ No newline at end of file diff --git a/mROA/Implementation/NetworkMessage.cs b/mROA/Implementation/NetworkMessage.cs index 3ef58fa..4a08543 100644 --- a/mROA/Implementation/NetworkMessage.cs +++ b/mROA/Implementation/NetworkMessage.cs @@ -11,5 +11,5 @@ public class NetworkMessage public enum MessageType { - Unknown, FinishedCommandExecution, ErrorCommandExecution, AcyncCancelCommandExecution, CallRequest + Unknown, FinishedCommandExecution, ErrorCommandExecution, AcyncCancelCommandExecution, CallRequest, IdAssigning } \ No newline at end of file diff --git a/mROA/Implementation/SharedObject.cs b/mROA/Implementation/SharedObject.cs new file mode 100644 index 0000000..931e5b2 --- /dev/null +++ b/mROA/Implementation/SharedObject.cs @@ -0,0 +1,62 @@ +using System.Text.Json.Serialization; +using mROA.Abstract; + +namespace mROA.Implementation; + +public static class TransmissionConfig +{ + public static IContextRepository? RealContextRepository { get; set; } + public static IContextRepository? RemoteEndpointContextRepository { get; set; } + public static int ProcessOwnerId { get; set; } + public static Dictionary ThreadsOwners { get; } = new(); +} + +public class SharedObject where T : notnull +{ + private IContextRepository GetDefaultContextRepository() => + (OwnerId == TransmissionConfig.ProcessOwnerId + ? TransmissionConfig.RealContextRepository + : TransmissionConfig.RemoteEndpointContextRepository) ?? + throw new NullReferenceException( + "DefaultContextRepository was not defined"); + + private int _contextId = -1; + public int OwnerId { get; } + + // ReSharper disable once MemberCanBePrivate.Global + public int ContextId + { + get => _contextId; + init + { + _contextId = value; + Value = GetDefaultContextRepository().GetObject(_contextId)!; + } + } + + [JsonIgnore] public T Value { get; private set; } + + public SharedObject() + { + } + + // ReSharper disable once UnusedMember.Global + public SharedObject(T value) + { + Value = value; + _contextId = GetDefaultContextRepository().GetObjectIndex(value); + OwnerId = TransmissionConfig.ThreadsOwners.TryGetValue(Environment.CurrentManagedThreadId, out var ownerId) + ? ownerId + : TransmissionConfig.ProcessOwnerId; + } + + public static implicit operator T(SharedObject value) => value.Value; + + public static implicit operator SharedObject(T value) => + new() + { + ContextId = value is IRemoteObject ro + ? TransmissionConfig.RemoteEndpointContextRepository!.GetObjectIndex(ro) + : TransmissionConfig.RealContextRepository!.GetObjectIndex(value) + }; +} \ No newline at end of file diff --git a/mROA/Implementation/TransmittedSharedObject.cs b/mROA/Implementation/TransmittedSharedObject.cs deleted file mode 100644 index 698e1d7..0000000 --- a/mROA/Implementation/TransmittedSharedObject.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text.Json.Serialization; -using mROA.Abstract; - -namespace mROA.Implementation; - -public static class TransmissionConfig -{ - public static IContextRepository? RealContextRepository { get; set; } - public static IContextRepository? RemoteEndpointContextRepository { get; set; } - public static int ProcessOwnerId { get; set; } -} - -public class TransmittedSharedObject where T : notnull -{ - private IContextRepository GetDefaultContextRepository() => (OwnerId == TransmissionConfig.ProcessOwnerId ? TransmissionConfig.RealContextRepository : TransmissionConfig.RemoteEndpointContextRepository) ?? - throw new NullReferenceException( - "DefaultContextRepository was not defined"); - - private int _contextId = -1; - public int OwnerId { get; init; } - // ReSharper disable once MemberCanBePrivate.Global - public int ContextId - { - get => _contextId; - init - { - _contextId = value; - Value = GetDefaultContextRepository().GetObject(_contextId)!; - } - } - - [JsonIgnore] - public T Value { get; private set; } - - public TransmittedSharedObject() - { - } - // ReSharper disable once UnusedMember.Global - public TransmittedSharedObject(T value) - { - Value = value; - _contextId = GetDefaultContextRepository().GetObjectIndex(value); - } - - public static implicit operator T(TransmittedSharedObject value) => value.Value; - - public static implicit operator TransmittedSharedObject(T value) => - new() { ContextId = value is IRemoteObject ro ? TransmissionConfig.RemoteEndpointContextRepository!.GetObjectIndex(ro) : TransmissionConfig.RealContextRepository!.GetObjectIndex(value) }; -} \ No newline at end of file