перевод на передачу с обозначением схемы
This commit is contained in:
@@ -11,4 +11,19 @@ public class LoadTestImp : ILoadTest
|
||||
{
|
||||
return last + 1;
|
||||
}
|
||||
|
||||
public int Last(int next)
|
||||
{
|
||||
return next - 1;
|
||||
}
|
||||
|
||||
public void C()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void A()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Example.Shared\Example.Shared.csproj" />
|
||||
<ProjectReference Include="..\Example.Shared\Example.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -16,7 +16,6 @@ mixer.Modules.Add(new FrontendContextRepository());
|
||||
mixer.Modules.Add(new JsonFrontendSerialisationModule());
|
||||
mixer.Modules.Add(new StreamBasedFrontendInteractionModule());
|
||||
mixer.Modules.Add(new NetworkFrontendBridge(new IPEndPoint(IPAddress.Loopback, 4567)));
|
||||
|
||||
mixer.Build();
|
||||
|
||||
mixer.GetModule<NetworkFrontendBridge>().Connect();
|
||||
@@ -25,6 +24,7 @@ var context = mixer.GetModule<FrontendContextRepository>();
|
||||
var factory = context.GetSingleObject(typeof(IPrinterFactory)) as IPrinterFactory;
|
||||
|
||||
|
||||
|
||||
var printer = factory.Create("Test");
|
||||
var name = printer.Value.GetName();
|
||||
Console.WriteLine("Printer name : {0}", name);
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\mROA.Codegen\mROA.Codegen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||
<ProjectReference Include="..\mROA\mROA.csproj"/>
|
||||
<ProjectReference Include="..\mROA.Codegen\mROA.Codegen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -7,4 +7,7 @@ namespace Example.Shared;
|
||||
public interface ILoadTest
|
||||
{
|
||||
int Next(int last);
|
||||
int Last(int next);
|
||||
void C();
|
||||
void A();
|
||||
}
|
||||
@@ -77,14 +77,15 @@ namespace {Namespace}
|
||||
/// </summary>
|
||||
/// <param name="context">Source generation context used to add source files.</param>
|
||||
/// <param name="compilation">Compilation used to provide access to the Semantic Model.</param>
|
||||
/// <param name="classDeclarations">Nodes annotated with the [Report] attribute that trigger the generate action.</param>
|
||||
/// <param name="classes">Nodes annotated with the [Report] attribute that trigger the generate action.</param>
|
||||
private void GenerateCode(SourceProductionContext context, Compilation compilation,
|
||||
ImmutableArray<InterfaceDeclarationSyntax> classDeclarations)
|
||||
ImmutableArray<InterfaceDeclarationSyntax> classes)
|
||||
{
|
||||
var methods = new List<(string, IMethodSymbol)>();
|
||||
var frontendContextRepo = new List<string>();
|
||||
// Go through all filtered class declarations.
|
||||
foreach (var classDeclarationSyntax in classDeclarations)
|
||||
var declarations = classes.ToList().OrderBy(i => i.Identifier.Text).ToList();
|
||||
foreach (var classDeclarationSyntax in declarations)
|
||||
{
|
||||
// We need to get semantic model of the class to retrieve metadata.
|
||||
var semanticModel = compilation.GetSemanticModel(classDeclarationSyntax.SyntaxTree);
|
||||
@@ -102,7 +103,7 @@ namespace {Namespace}
|
||||
|
||||
// Go through all class members with a particular type (property) to generate method lines.
|
||||
var methodBody = classSymbol.GetMembers()
|
||||
.OfType<IMethodSymbol>();
|
||||
.OfType<IMethodSymbol>().OrderBy(i => i.Name);
|
||||
|
||||
var originalName = className;
|
||||
// Build up the source code
|
||||
@@ -204,7 +205,7 @@ partial class {className} (int id, ISerialisationModule.IFrontendSerialisationMo
|
||||
var methodsStringed = methods.Select(i =>
|
||||
$"typeof({i.Item1}).GetMethod(\"{i.Item2.Name}\", [{string.Join(", ", i.Item2.Parameters.Select(p => $"typeof({p.Type.ToDisplayString()})"))}])")
|
||||
.ToList();
|
||||
|
||||
|
||||
var coCodegenRepoCode = @$"// <auto-generated/>
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
@@ -212,10 +213,10 @@ using mROA.Abstract;
|
||||
|
||||
namespace mROA.Codegen;
|
||||
|
||||
public class CoCodegenMethodRepository :IMethodRepository
|
||||
public class CoCodegenMethodRepository : IMethodRepository
|
||||
{{
|
||||
private readonly List<MethodInfo> _methods = [
|
||||
{string.Join(", \r\n\t\t", methodsStringed)}
|
||||
{string.Join(", // test comment\r\n\t\t", methodsStringed)}
|
||||
];
|
||||
public MethodInfo GetMethod(int id)
|
||||
{{
|
||||
@@ -310,6 +311,5 @@ public class FrontendContextRepository : IContextRepository
|
||||
";
|
||||
context.AddSource("FrontendContextRepository.g.cs", SourceText.From(fronendRepoCode, Encoding.UTF8));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ namespace mROA.Abstract;
|
||||
public interface IInteractionModule : IInjectableModule
|
||||
{
|
||||
void SendTo(int clientId, byte[] message);
|
||||
void RegisterSourse(Stream stream);
|
||||
void RegisterSource(Stream stream);
|
||||
public interface IFrontendInteractionModule : IInjectableModule
|
||||
{
|
||||
public Task<byte[]> ReceiveMessage();
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace mROA.Abstract;
|
||||
|
||||
public interface ISerialisationModule : IInjectableModule
|
||||
{
|
||||
void HandleIncomingRequest(int clientId, byte[] command);
|
||||
void PostResponse(ICommandExecution call);
|
||||
void HandleIncomingRequest(int clientId, byte[] message);
|
||||
void PostResponse(NetworkMessage message, int clientId);
|
||||
public interface IFrontendSerialisationModule : IInjectableModule
|
||||
{
|
||||
Task<T> GetNextCommandExecution<T>(Guid requestId) where T : ICommandExecution;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using mROA.Abstract;
|
||||
|
||||
@@ -10,26 +11,39 @@ public class JsonSerialisationModule : ISerialisationModule
|
||||
private IExecuteModule? _executeModule;
|
||||
private IMethodRepository? _methodRepository;
|
||||
|
||||
public void HandleIncomingRequest(int clientId, byte[] command)
|
||||
public void HandleIncomingRequest(int clientId, byte[] message)
|
||||
{
|
||||
DefaultCallRequest request = JsonSerializer.Deserialize<DefaultCallRequest>(command)!;
|
||||
NetworkMessage input = JsonSerializer.Deserialize<NetworkMessage>(message)!;
|
||||
|
||||
if (request.Parameter is not null)
|
||||
if (input.SchemaId == MessageType.CallRequest)
|
||||
{
|
||||
var parameter = _methodRepository!.GetMethod(request.CommandId).GetParameters().First().ParameterType;
|
||||
request.Parameter = ((JsonElement)request.Parameter).Deserialize(parameter);
|
||||
}
|
||||
var command = JsonSerializer.Deserialize<DefaultCallRequest>(input.Data);
|
||||
if (command.Parameter is not null)
|
||||
{
|
||||
var parameter = _methodRepository!.GetMethod(command.CommandId).GetParameters().First().ParameterType;
|
||||
command.Parameter = ((JsonElement)command.Parameter).Deserialize(parameter);
|
||||
}
|
||||
|
||||
var response = _executeModule!.Execute(request);
|
||||
response.ClientId = clientId;
|
||||
PostResponse(response);
|
||||
var response = _executeModule!.Execute(command);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostResponse(ICommandExecution call)
|
||||
public void PostResponse(NetworkMessage message, int clientId)
|
||||
{
|
||||
var texted = JsonSerializer.Serialize(call, call.GetType());
|
||||
var texted = JsonSerializer.Serialize(message);
|
||||
var binary = Encoding.UTF8.GetBytes(texted);
|
||||
_dataSource!.SendTo(call.ClientId, binary);
|
||||
_dataSource!.SendTo(clientId, binary);
|
||||
}
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
@@ -41,5 +55,4 @@ public class JsonSerialisationModule : ISerialisationModule
|
||||
if (dependency is IMethodRepository methodRepository)
|
||||
_methodRepository = methodRepository;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@ public class NetworkGatewayModule(IPEndPoint endpoint) : IGatewayModule
|
||||
{
|
||||
var client = _tcpListener.AcceptTcpClient();
|
||||
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
|
||||
_interactionModule.RegisterSourse(client.GetStream());
|
||||
_interactionModule.RegisterSource(client.GetStream());
|
||||
Console.WriteLine("Client registered");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ public class StreamBasedInteractionModule : IInteractionModule
|
||||
private readonly Dictionary<int, Stream> _streams = new();
|
||||
private Action<int, byte[]>? _handler;
|
||||
|
||||
public void RegisterSourse(Stream stream)
|
||||
public void RegisterSource(Stream stream)
|
||||
{
|
||||
var id = Random.Shared.Next();
|
||||
_streams.Add(id, stream);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class ExceptionCommandExecution : ICommandExecution
|
||||
{
|
||||
public Guid CallRequestId { get; init; }
|
||||
public int ClientId { get; set; }
|
||||
public int CommandId { get; init; }
|
||||
public required string Exception { get; set; }
|
||||
}
|
||||
-14
@@ -17,18 +17,4 @@ public class FinalCommandExecution : ICommandExecution
|
||||
public class FinalCommandExecution<T> : FinalCommandExecution
|
||||
{
|
||||
public T? Result { get; init; }
|
||||
}
|
||||
|
||||
public class TypedFinalCommandExecution : FinalCommandExecution<object>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Type? Type { get; set; }
|
||||
}
|
||||
|
||||
public class ExceptionCommandExecution : ICommandExecution
|
||||
{
|
||||
public Guid CallRequestId { get; init; }
|
||||
public int ClientId { get; set; }
|
||||
public int CommandId { get; init; }
|
||||
public required string Exception { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class TypedFinalCommandExecution : FinalCommandExecution<object>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Type? Type { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation.Frontend;
|
||||
|
||||
public class JsonFrontendCallbackSerializationModule : ISerialisationModule
|
||||
{
|
||||
private IInteractionModule.IFrontendInteractionModule? _interactionModule;
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
{
|
||||
if (dependency is IInteractionModule.IFrontendInteractionModule interactionModule)
|
||||
_interactionModule = interactionModule;
|
||||
}
|
||||
|
||||
public void HandleIncomingRequest(int clientId, byte[] message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void PostResponse(NetworkMessage message, int clientId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public class JsonFrontendSerialisationModule
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new Exception("Interaction module not initialized");
|
||||
|
||||
|
||||
var receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
var parsed = JsonSerializer.Deserialize<T>(receiveMessage)!;
|
||||
while (parsed.CallRequestId != requestId)
|
||||
@@ -29,32 +29,37 @@ public class JsonFrontendSerialisationModule
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new Exception("Interaction module not initialized");
|
||||
|
||||
var receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
// var str = Encoding.UTF8.GetString(receiveMessage);
|
||||
var document = JsonDocument.Parse(receiveMessage);
|
||||
if (document.RootElement.TryGetProperty("Exception", out var exceptionElement))
|
||||
{
|
||||
throw new RemoteException(exceptionElement.GetString()!) { CallRequestId = requestId };
|
||||
}
|
||||
|
||||
var parsed = document.Deserialize<FinalCommandExecution<T>>()!;
|
||||
while (parsed.CallRequestId != requestId)
|
||||
var receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
|
||||
var message = JsonSerializer.Deserialize<NetworkMessage>(receiveMessage)!;
|
||||
while (message.Id != requestId)
|
||||
{
|
||||
receiveMessage = await _interactionModule.ReceiveMessage();
|
||||
parsed = JsonSerializer.Deserialize<FinalCommandExecution<T>>(receiveMessage)!;
|
||||
message = JsonSerializer.Deserialize<NetworkMessage>(receiveMessage)!;
|
||||
}
|
||||
|
||||
return parsed;
|
||||
if (message.SchemaId == MessageType.ErrorCommandExecution)
|
||||
{
|
||||
throw new RemoteException(JsonSerializer.Deserialize<ExceptionCommandExecution>(message.Data)!.Exception)
|
||||
{ CallRequestId = requestId };
|
||||
}
|
||||
|
||||
return JsonSerializer.Deserialize<FinalCommandExecution<T>>(message.Data)!;
|
||||
}
|
||||
|
||||
public void PostCallRequest(ICallRequest callRequest)
|
||||
{
|
||||
if (_interactionModule is null)
|
||||
throw new Exception("Interaction module not initialized");
|
||||
|
||||
var post = JsonSerializer.Serialize(callRequest, callRequest.GetType());
|
||||
_interactionModule.PostMessage(Encoding.UTF8.GetBytes(post));
|
||||
|
||||
var post = JsonSerializer.SerializeToUtf8Bytes(callRequest, callRequest.GetType());
|
||||
_interactionModule.PostMessage(JsonSerializer.SerializeToUtf8Bytes(new NetworkMessage
|
||||
{
|
||||
Id = callRequest.CallRequestId,
|
||||
Data = post,
|
||||
SchemaId = MessageType.CallRequest
|
||||
}));
|
||||
}
|
||||
|
||||
public void Inject<T>(T dependency)
|
||||
@@ -62,7 +67,6 @@ public class JsonFrontendSerialisationModule
|
||||
if (dependency is IInteractionModule.IFrontendInteractionModule interactionModule)
|
||||
_interactionModule = interactionModule;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class RemoteException(string error) : Exception
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using mROA.Abstract;
|
||||
|
||||
namespace mROA.Implementation;
|
||||
|
||||
public class NetworkMessage
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public MessageType SchemaId { get; set; }
|
||||
public byte[] Data { get; set; }
|
||||
}
|
||||
|
||||
public enum MessageType
|
||||
{
|
||||
Unknown, FinishedCommandExecution, ErrorCommandExecution, AcyncCancelCommandExecution, CallRequest
|
||||
}
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Title>mROA</Title>
|
||||
<Version>1.1.3</Version>
|
||||
<Version>2.0.0</Version>
|
||||
<Authors>YaslePoy</Authors>
|
||||
<Description>Fast and easy RPC with contex</Description>
|
||||
<RepositoryUrl>https://github.com/YaslePoy/mROA</RepositoryUrl>
|
||||
|
||||
Reference in New Issue
Block a user