Small change of message type assigning

This commit is contained in:
2025-03-31 10:34:04 +03:00
parent 62dde889d8
commit 2851a85d1c
38 changed files with 78 additions and 711 deletions
-22
View File
@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>BasicDemo</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\mROA.CodegenTools\mROA.CodegenTools.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="exampleTemplate.cstmpl" />
<EmbeddedResource Include="exampleTemplate.cstmpl">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
</Project>
-25
View File
@@ -1,25 +0,0 @@
// See https://aka.ms/new-console-template for more information
using mROA.CodegenTools;
// var doc = new TemplateDocument();
// doc.Parts = new List<ITemplateSection>
// {
// new LiteralTemplateSection("teset text", doc),
// new DefineTemplateSection(" another text which is dinided, bun not placed ", "text define", doc),
// new LinkTemplateSection("text define", doc),
// new LinkTemplateSection("text define", doc),
// new LinkTemplateSection("text define", doc),
// new LiteralTemplateSection(" = = = ", doc),
// new InsertTemplatePart("insert", doc),
// new LinkTemplateSection("post", doc)
// };
//
// doc.Insert("insert", "inserted text by insert template => ");
// doc.Parts.Add(new DefineTemplateSection("post added", "post", doc));
// Console.WriteLine(doc.Compile());
var doc = TemplateReader.FromEmbeddedResource("exampleTemplate.cstmpl");
doc.Insert("ctorInserting", "test inserting");
Console.WriteLine(doc.Compile());
Console.WriteLine(doc.Parts.Count);
-19
View File
@@ -1,19 +0,0 @@
public class A
{
<!L linkTagA>
<!L linkTag>
<!L linkTag>
Some literal for test
<!D linkTagA>test text with definition in template<!D>
<!I ctorInserting>
<!I methodInserting R>
<!T MethodTemplate>
public void <!L methodName>()
{
Console.WriteLine("<!L printText>");
}
<!T>
}
+1 -1
View File
@@ -39,7 +39,7 @@ namespace mROA.Codegen
Parameters = new object[] { <!L transferParameters> } Parameters = new object[] { <!L transferParameters> }
}; };
module.PostCallMessageAsync(request.Id, MessageType.EventRequest, request); module.PostCallMessageAsync(request.Id, EMessageType.EventRequest, request);
}; };
<!T> <!T>
} }
-4
View File
@@ -173,10 +173,6 @@ namespace mROA.Codegen
{ {
var coCodegenRepoCode = _methodRepoTemplate.Compile(); var coCodegenRepoCode = _methodRepoTemplate.Compile();
#if !DONT_ADD #if !DONT_ADD
var template = TemplateReader.FromEmbeddedResource("TestClass.cstmpl");
template.AddDefine("param", "System.Int32 i");
context.AddSource("TestClass.g.cs", SourceText.From(template.Compile(), Encoding.UTF8));
context.AddSource("CoCodegenMethodRepository.g.cs", SourceText.From(coCodegenRepoCode, Encoding.UTF8)); context.AddSource("CoCodegenMethodRepository.g.cs", SourceText.From(coCodegenRepoCode, Encoding.UTF8));
#endif #endif
} }
@@ -1,32 +0,0 @@
using System;
namespace mROA.CodegenTools
{
public class DefineTemplateSection : ITagged
{
public TemplateDocument Context { get; set; }
public string StoredText { get; }
private readonly string _tag;
public DefineTemplateSection(string storedText, string tag, TemplateDocument context)
{
StoredText = storedText;
_tag = tag;
Context = context;
}
public string Tag => _tag;
public int TargetLength => StoredText.Length;
public override string ToString()
{
return StoredText;
}
public object Clone()
{
return new DefineTemplateSection(StoredText, _tag, Context);
}
}
}
-21
View File
@@ -1,21 +0,0 @@
using System;
namespace mROA.CodegenTools
{
public interface ITemplateSection : ICloneable
{
TemplateDocument Context { get; set; }
int TargetLength { get; }
}
public interface IBaking
{
string Bake();
}
public interface ITagged : ITemplateSection
{
string Tag { get; }
}
}
-25
View File
@@ -1,25 +0,0 @@
namespace mROA.CodegenTools
{
public class InnerTemplateSection : ITemplateSection, ITagged
{
private readonly string _tag;
public TemplateDocument Context { get; set; }
public int TargetLength => 0;
public string Tag => _tag;
public TemplateDocument InnerTemplate { get; }
public InnerTemplateSection(string tag, TemplateDocument innerTemplate, TemplateDocument context)
{
_tag = tag;
Context = context;
InnerTemplate = innerTemplate;
}
public object Clone()
{
return new InnerTemplateSection(_tag, InnerTemplate, Context);
}
}
}
-74
View File
@@ -1,74 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace mROA.CodegenTools
{
public class InsertTemplatePart : ITagged, IBaking
{
private object _insertedValue;
private string _tag;
public string Tag => _tag;
public TemplateDocument Context { get; set; }
public readonly List<string> Parameters;
public InsertTemplatePart(string tag, TemplateDocument context, params string[] parameters)
{
_tag = tag;
Parameters = parameters.ToList();
Context = context;
}
private bool IsInserted(object value)
{
if (Parameters.IndexOf("R") == 0) return false;
ProduceInserted(value);
return true;
}
private void ProduceInserted(object value)
{
var currentIndex = Context.Parts.IndexOf(this);
var clone = (InsertTemplatePart)MemberwiseClone();
clone._tag += "+";
clone._insertedValue = value;
Context.Parts.Insert(currentIndex, clone);
}
public void Setup(object value)
{
if (!(value is string) && !(value is ITemplateSection) )
return;
if (IsInserted(value))
return;
_insertedValue = value;
}
public int TargetLength => 0;
public string Bake()
{
switch (_insertedValue)
{
case null:
return string.Empty;
case string s:
return s;
default:
return ((ITemplateSection)_insertedValue).ToString();
}
}
public object Clone()
{
return new InsertTemplatePart(_tag, Context, Parameters.ToArray());
}
}
}
-43
View File
@@ -1,43 +0,0 @@
using System.Linq;
namespace mROA.CodegenTools
{
public class LinkTemplateSection : ITemplateSection, IBaking
{
private readonly string _linkedTag;
public LinkTemplateSection(string linkedTag, TemplateDocument context)
{
_linkedTag = linkedTag;
Context = context;
}
public TemplateDocument Context { get; set; }
public string LinkedTag => _linkedTag;
public int TargetLength
{
get
{
var attached = Context[_linkedTag];
return attached?.TargetLength ?? 0;
}
}
public string Bake()
{
return Context[_linkedTag]?.ToString();
}
public override string ToString()
{
return $"{nameof(LinkedTag)}: {_linkedTag}";
}
public object Clone()
{
return new LinkTemplateSection(_linkedTag, Context);
}
}
}
@@ -1,31 +0,0 @@
namespace mROA.CodegenTools
{
public class LiteralTemplateSection : ITemplateSection, IBaking
{
private string _internalText;
public LiteralTemplateSection(string internalText, TemplateDocument context)
{
_internalText = internalText;
Context = context;
}
public TemplateDocument Context { get; set; }
public int TargetLength => _internalText.Length;
public string Bake()
{
return ToString();
}
public override string ToString()
{
return _internalText;
}
public object Clone()
{
return new LiteralTemplateSection(_internalText, Context);
}
}
}
@@ -1,29 +0,0 @@
using System;
namespace mROA.CodegenTools
{
public class ProgrammableTextSection : ITemplateSection, IBaking
{
public TemplateDocument Context { get; set; }
public int TargetLength => 0;
private Func<object, string> _bakeFunc;
public ProgrammableTextSection(Func<object, string> bakeFunc, TemplateDocument context)
{
_bakeFunc = bakeFunc;
Context = context;
}
public string Bake()
{
return _bakeFunc(Context.AdditionalContext);
}
public object Clone()
{
return new ProgrammableTextSection(_bakeFunc, Context);
}
}
}
@@ -1,24 +0,0 @@
using System;
namespace mROA.CodegenTools
{
public class DefineSectionReader : LeadingTextSectionReader
{
public DefineSectionReader() : base("<!D")
{
}
public override ITemplateSection ExtractSection(ref int index, TemplateDocument document)
{
var tagEnd = TemplateText.IndexOf(">", index, StringComparison.Ordinal);
var sectionName = GetTagValue(index, tagEnd);
tagEnd += 1;
var endIndex = TemplateText.IndexOf("<!D>", tagEnd, StringComparison.Ordinal);
var storedText = TemplateText.Substring(tagEnd, endIndex - tagEnd);
index = endIndex + 4;
PassCaretToCloseSymbol();
PassCaretToCloseSymbol();
return new DefineTemplateSection(storedText, sectionName, document);
}
}
}
@@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace mROA.CodegenTools
{
public interface ISectionReader
{
string TemplateText { get; set; }
int GetNextSectionIndex(int currentIndex);
ITemplateSection ExtractSection(ref int index, TemplateDocument document);
}
}
@@ -1,39 +0,0 @@
using System;
namespace mROA.CodegenTools
{
public class InnerTemplateSectionReader : LeadingTextSectionReader
{
public InnerTemplateSectionReader()
: base("<!T")
{
}
public override ITemplateSection ExtractSection(ref int index, TemplateDocument document)
{
var end = FindEnd(index + 4);
var from = index;
var to = PassCaretToCloseSymbol();
index = to;
var tagName = GetTagValue(from, to);
var innerDocText = TemplateText.Substring(index, end - index);
var innerDoc = TemplateReader.Parse(innerDocText);
_currentCaretPosition = end + 4;
index = _currentCaretPosition;
return new InnerTemplateSection(tagName, innerDoc, document);
}
private int FindEnd(int start)
{
var endSymbol = TemplateText.IndexOf("<!T>", start, StringComparison.Ordinal);
var innerStartSymbol = TemplateText.IndexOf("<!T ", start, StringComparison.Ordinal);
if (endSymbol < innerStartSymbol || innerStartSymbol == -1)
return endSymbol;
return FindEnd(endSymbol + 4);
}
}
}
@@ -1,24 +0,0 @@
using System.Linq;
namespace mROA.CodegenTools
{
public class InsertSectionReader : LeadingTextSectionReader
{
public InsertSectionReader() : base("<!I")
{
}
public override ITemplateSection ExtractSection(ref int index, TemplateDocument document)
{
var from = index;
var to = PassCaretToCloseSymbol();
index = to;
var tagText = GetTagValue(from, to);
var parts = tagText.Split(' ');
return new InsertTemplatePart(parts[0], document, parts.Skip(1).ToArray());
}
}
}
@@ -1,38 +0,0 @@
using System;
namespace mROA.CodegenTools
{
public abstract class LeadingTextSectionReader : ISectionReader
{
protected int _currentCaretPosition;
private string _tagLeading;
protected LeadingTextSectionReader(string tagLeading)
{
_tagLeading = tagLeading + " ";
}
protected int PassCaretToCloseSymbol()
{
_currentCaretPosition = TemplateText.IndexOf(">", _currentCaretPosition, StringComparison.Ordinal) + 1;
return _currentCaretPosition;
}
public string TemplateText { get; set; }
public int GetNextSectionIndex(int currentIndex)
{
_currentCaretPosition = Math.Max(currentIndex, _currentCaretPosition);
var index = TemplateText.IndexOf(_tagLeading, _currentCaretPosition, StringComparison.Ordinal);
_currentCaretPosition = index;
return index;
}
public abstract ITemplateSection ExtractSection(ref int index, TemplateDocument document);
protected string GetTagValue(int from, int to)
{
return TemplateText.Substring(from + 4, to - from - 5);
}
}
}
@@ -1,20 +0,0 @@
namespace mROA.CodegenTools
{
public class LinkSectionReader : LeadingTextSectionReader
{
public LinkSectionReader() : base("<!L")
{
}
public override ITemplateSection ExtractSection(ref int index, TemplateDocument document)
{
var from = index;
var to = PassCaretToCloseSymbol();
index = to;
var tagText = GetTagValue(from, to);
return new LinkTemplateSection(tagText, document);
}
}
}
@@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace mROA.CodegenTools
{
public static class TemplateReader
{
private static readonly List<Type> ReaderTypes = new List<Type>
{
typeof(DefineSectionReader),
typeof(InsertSectionReader),
typeof(LinkSectionReader),
typeof(InnerTemplateSectionReader)
};
public static TemplateDocument Parse(string templateText)
{
int currentIndex = 0;
var activeReaders = new List<ISectionReader>();
foreach (var readerType in ReaderTypes)
{
var reader = Activator.CreateInstance(readerType) as ISectionReader;
reader.TemplateText = templateText;
activeReaders.Add(reader);
}
var doc = new TemplateDocument();
while (currentIndex < templateText.Length)
{
List<(ISectionReader reader, int index)> indices = activeReaders.Select(i => ((ISectionReader Readers, int index))(i, i.GetNextSectionIndex(currentIndex))).Where(i => i.index > -1).ToList();
int minIndex = templateText.Length;
ISectionReader minReader = null;
if (indices.Count != 0)
{
minIndex = indices.Min(i => i.index);
minReader = indices.FirstOrDefault(i => i.index == minIndex).reader;
if (indices.Count != activeReaders.Count)
{
activeReaders = indices.Select(i => i.reader).ToList();
}
}
if (currentIndex != minIndex)
{
var literalText = templateText.Substring(currentIndex, minIndex - currentIndex);
var literal =
new LiteralTemplateSection(literalText, doc);
doc.Parts.Add(literal);
currentIndex = minIndex;
}
if (indices.Count != 0)
{
var section = minReader.ExtractSection(ref currentIndex, doc);
doc.Parts.Add(section);
}
}
return doc;
}
public static TemplateDocument FromEmbeddedResource(string resourceName)
{
return FromEmbeddedResource(resourceName, Assembly.GetCallingAssembly());
}
public static TemplateDocument FromEmbeddedResource(string resourceName, Assembly assembly)
{
var fileName = assembly.GetManifestResourceNames().First(n => n.EndsWith(resourceName));
var res = assembly.GetManifestResourceStream(fileName);
var reader = new StreamReader(res);
var templateText = reader.ReadToEnd();
return Parse(templateText);
}
}
}
-54
View File
@@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace mROA.CodegenTools
{
public class TemplateDocument : ICloneable
{
public List<ITemplateSection> Parts { get; set; } = new List<ITemplateSection>();
public object AdditionalContext { get; set; }
public ITagged this[string tag] => Parts.OfType<ITagged>().FirstOrDefault(i => i.Tag == tag);
public void Insert(string tag, object value)
{
var selectedPart = this[tag];
if (selectedPart is InsertTemplatePart itp)
{
itp.Setup(value);
}
}
public string Compile()
{
var approximatelyLength = Parts.Sum(i => i.TargetLength);
var stringBuilder = new StringBuilder(approximatelyLength);
foreach (var part in Parts.OfType<IBaking>())
{
var baked = part.Bake();
stringBuilder.Append(baked);
}
return stringBuilder.ToString();
}
public object Clone()
{
var cloneDoc = new TemplateDocument
{
AdditionalContext = AdditionalContext is ICloneable c ? c.Clone() : AdditionalContext
};
cloneDoc.Parts = Parts.Select(i =>
{
var clone = i.Clone() as ITemplateSection;
clone.Context = cloneDoc;
return clone;
}).ToList();
return cloneDoc;
}
}
}
@@ -1,8 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8</LangVersion>
</PropertyGroup>
</Project>
+1 -1
View File
@@ -37,7 +37,7 @@ namespace mROA.Test
foreach (var guid in guids) foreach (var guid in guids)
{ {
_interactionModuleB.PostMessage(new NetworkMessage { Id = guid, Data = "Hello user"u8.ToArray() }); _interactionModuleB.PostMessage(new NetworkMessageHeader { Id = guid, Data = "Hello user"u8.ToArray() });
} }
}); });
-13
View File
@@ -23,12 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mROA.Cbor", "mROA.Cbor\mROA
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TotalDemo", "TotalDemo", "{FC4FA752-10A7-4D78-A7C2-9BCD8A81FB5E}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TotalDemo", "TotalDemo", "{FC4FA752-10A7-4D78-A7C2-9BCD8A81FB5E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mROA.CodegenTools", "mROA.CodegenTools\mROA.CodegenTools.csproj", "{2A2821B7-E5C5-443A-9801-9622493594A0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Codegen", "Codegen", "{3DB22457-E65B-426F-B3DD-08C615132B3E}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Codegen", "Codegen", "{3DB22457-E65B-426F-B3DD-08C615132B3E}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codegen.Basic", "Codegen.Basic\Codegen.Basic.csproj", "{87396E86-D7ED-4556-AB50-F3696FEF9072}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -67,14 +63,6 @@ Global
{6211E4EA-13FD-4EB1-8E6A-C0173DD0784A}.Debug|Any CPU.Build.0 = Debug|Any CPU {6211E4EA-13FD-4EB1-8E6A-C0173DD0784A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6211E4EA-13FD-4EB1-8E6A-C0173DD0784A}.Release|Any CPU.ActiveCfg = Release|Any CPU {6211E4EA-13FD-4EB1-8E6A-C0173DD0784A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6211E4EA-13FD-4EB1-8E6A-C0173DD0784A}.Release|Any CPU.Build.0 = Release|Any CPU {6211E4EA-13FD-4EB1-8E6A-C0173DD0784A}.Release|Any CPU.Build.0 = Release|Any CPU
{2A2821B7-E5C5-443A-9801-9622493594A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A2821B7-E5C5-443A-9801-9622493594A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A2821B7-E5C5-443A-9801-9622493594A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A2821B7-E5C5-443A-9801-9622493594A0}.Release|Any CPU.Build.0 = Release|Any CPU
{87396E86-D7ED-4556-AB50-F3696FEF9072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87396E86-D7ED-4556-AB50-F3696FEF9072}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87396E86-D7ED-4556-AB50-F3696FEF9072}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87396E86-D7ED-4556-AB50-F3696FEF9072}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -85,6 +73,5 @@ Global
{9BD25A13-3165-47C0-9EAA-5C59EC490E32} = {FC4FA752-10A7-4D78-A7C2-9BCD8A81FB5E} {9BD25A13-3165-47C0-9EAA-5C59EC490E32} = {FC4FA752-10A7-4D78-A7C2-9BCD8A81FB5E}
{E7703F5B-F2A6-4A88-AA57-EBB1E38D533E} = {FC4FA752-10A7-4D78-A7C2-9BCD8A81FB5E} {E7703F5B-F2A6-4A88-AA57-EBB1E38D533E} = {FC4FA752-10A7-4D78-A7C2-9BCD8A81FB5E}
{3DB22457-E65B-426F-B3DD-08C615132B3E} = {EAE92F5A-664C-41AB-8811-5885524B5347} {3DB22457-E65B-426F-B3DD-08C615132B3E} = {EAE92F5A-664C-41AB-8811-5885524B5347}
{87396E86-D7ED-4556-AB50-F3696FEF9072} = {3DB22457-E65B-426F-B3DD-08C615132B3E}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
+2 -1
View File
@@ -1,8 +1,9 @@
using System; using System;
using mROA.Implementation;
namespace mROA.Abstract namespace mROA.Abstract
{ {
public interface ICommandExecution public interface ICommandExecution : INetworkMessage
{ {
Guid Id { get; set; } Guid Id { get; set; }
} }
+5 -5
View File
@@ -9,10 +9,10 @@ namespace mROA.Abstract
{ {
int ConnectionId { get; } int ConnectionId { get; }
public Stream? BaseStream { get; set; } public Stream? BaseStream { get; set; }
Task<NetworkMessage> GetNextMessageReceiving(); Task<NetworkMessageHeader> GetNextMessageReceiving();
Task PostMessage(NetworkMessage message); Task PostMessage(NetworkMessageHeader messageHeader);
void HandleMessage(NetworkMessage message); void HandleMessage(NetworkMessageHeader messageHeader);
NetworkMessage[] UnhandledMessages { get; } NetworkMessageHeader[] UnhandledMessages { get; }
NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate); NetworkMessageHeader? FirstByFilter(Predicate<NetworkMessageHeader> predicate);
} }
} }
+7 -7
View File
@@ -9,17 +9,17 @@ namespace mROA.Abstract
{ {
int Id { get; } int Id { get; }
Task<T> GetMessageAsync<T>(Guid? requestId = null, MessageType? messageType = null, Task<T> GetMessageAsync<T>(Guid? requestId = null, EMessageType? messageType = null,
CancellationToken token = default); CancellationToken token = default);
T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null); T GetMessage<T>(Guid? requestId = null, EMessageType? messageType = null);
Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null, Task<byte[]> GetRawMessage(Guid? requestId = null, EMessageType? messageType = null,
CancellationToken token = default); CancellationToken token = default);
Task PostCallMessageAsync<T>(Guid id, MessageType messageType, T payload) where T : notnull; Task PostCallMessageAsync<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull;
Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType); Task PostCallMessageAsync(Guid id, EMessageType eMessageType, object payload, Type payloadType);
void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull; void PostCallMessage<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull;
void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType); void PostCallMessage(Guid id, EMessageType eMessageType, object payload, Type payloadType);
} }
} }
@@ -198,7 +198,7 @@ namespace mROA.Implementation.Backend
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository; TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id); multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id);
representationModule.PostCallMessage(command.Id, MessageType.FinishedCommandExecution, payload); representationModule.PostCallMessage(command.Id, EMessageType.FinishedCommandExecution, payload);
multiClientOwnershipRepository?.FreeOwnership(); multiClientOwnershipRepository?.FreeOwnership();
}); });
@@ -240,7 +240,7 @@ namespace mROA.Implementation.Backend
var multiClientOwnershipRepository = var multiClientOwnershipRepository =
TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository; TransmissionConfig.OwnershipRepository as MultiClientOwnershipRepository;
multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id); multiClientOwnershipRepository?.RegisterOwnership(representationModule.Id);
representationModule.PostCallMessage(command.Id, MessageType.FinishedCommandExecution, representationModule.PostCallMessage(command.Id, EMessageType.FinishedCommandExecution,
payload); payload);
multiClientOwnershipRepository?.FreeOwnership(); multiClientOwnershipRepository?.FreeOwnership();
}); });
@@ -75,9 +75,9 @@ namespace mROA.Implementation.Backend
interaction.BaseStream = client.GetStream(); interaction.BaseStream = client.GetStream();
interaction.PostMessage(new NetworkMessage interaction.PostMessage(new NetworkMessageHeader
{ {
Id = Guid.NewGuid(), SchemaId = MessageType.IdAssigning, Id = Guid.NewGuid(), EMessageType = EMessageType.IdAssigning,
Data = _serialization!.Serialize(new IdAssignment { Id = -interaction.ConnectionId }) Data = _serialization!.Serialize(new IdAssignment { Id = -interaction.ConnectionId })
}); });
_hub!.RegisterInteraction(interaction); _hub!.RegisterInteraction(interaction);
@@ -6,5 +6,6 @@ namespace mROA.Implementation.CommandExecution
public class AsyncCommandExecution : ICommandExecution public class AsyncCommandExecution : ICommandExecution
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public EMessageType MessageType => EMessageType.Unknown;
} }
} }
@@ -7,6 +7,7 @@ namespace mROA.Implementation.CommandExecution
public class ExceptionCommandExecution : ICommandExecution public class ExceptionCommandExecution : ICommandExecution
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public EMessageType MessageType => EMessageType.ExceptionCommandExecution;
public string Exception { get; set; } public string Exception { get; set; }
public RemoteException GetException() public RemoteException GetException()
@@ -8,6 +8,7 @@ namespace mROA.Implementation.CommandExecution
public class FinalCommandExecution : ICommandExecution public class FinalCommandExecution : ICommandExecution
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public EMessageType MessageType => EMessageType.FinishedCommandExecution;
} }
public class FinalCommandExecution<T> : FinalCommandExecution public class FinalCommandExecution<T> : FinalCommandExecution
@@ -40,10 +40,10 @@ namespace mROA.Implementation.Frontend
_tcpClient.Connect(_ipEndPoint); _tcpClient.Connect(_ipEndPoint);
_interactionModule.BaseStream = _tcpClient.GetStream(); _interactionModule.BaseStream = _tcpClient.GetStream();
var welcomeMessage = _interactionModule.GetNextMessageReceiving().GetAwaiter().GetResult(); var welcomeMessage = _interactionModule.GetNextMessageReceiving().GetAwaiter().GetResult();
if (welcomeMessage.SchemaId != MessageType.IdAssigning) if (welcomeMessage.EMessageType != EMessageType.IdAssigning)
{ {
throw new Exception( throw new Exception(
$"Incorrect message type. Must be IdAssigning, current : {welcomeMessage.SchemaId.ToString()}"); $"Incorrect message type. Must be IdAssigning, current : {welcomeMessage.EMessageType.ToString()}");
} }
@@ -73,13 +73,13 @@ namespace mROA.Implementation.Frontend
var token = tokenSource.Token; var token = tokenSource.Token;
var defaultRequest = var defaultRequest =
_representationModule!.GetMessageAsync<DefaultCallRequest>( _representationModule!.GetMessageAsync<DefaultCallRequest>(
messageType: MessageType.CallRequest, token: token); messageType: EMessageType.CallRequest, token: token);
var cancelRequest = var cancelRequest =
_representationModule!.GetMessageAsync<CancelRequest>( _representationModule!.GetMessageAsync<CancelRequest>(
messageType: MessageType.CancelRequest, token: token); messageType: EMessageType.CancelRequest, token: token);
var eventRequest = var eventRequest =
_representationModule!.GetMessageAsync<DefaultCallRequest>( _representationModule!.GetMessageAsync<DefaultCallRequest>(
messageType: MessageType.EventRequest, token: token); messageType: EMessageType.EventRequest, token: token);
Task.WaitAny(defaultRequest, cancelRequest, eventRequest); Task.WaitAny(defaultRequest, cancelRequest, eventRequest);
#if TRACE #if TRACE
Console.WriteLine("Request received"); Console.WriteLine("Request received");
@@ -135,13 +135,9 @@ namespace mROA.Implementation.Frontend
var result = _executeModule!.Execute(request, _realContextRepository!, _representationModule!); var result = _executeModule!.Execute(request, _realContextRepository!, _representationModule!);
var resultType = result switch var resultType = result.MessageType;
{
FinalCommandExecution => MessageType.FinishedCommandExecution, if (resultType == EMessageType.Unknown)
ExceptionCommandExecution => MessageType.ExceptionCommandExecution,
_ => MessageType.Unknown
};
if (resultType == MessageType.Unknown)
{ {
return; return;
} }
+3 -1
View File
@@ -1,7 +1,9 @@
namespace mROA.Implementation namespace mROA.Implementation
{ {
public class IdAssignment public class IdAssignment : INetworkMessage
{ {
public int Id { get; set; } public int Id { get; set; }
public EMessageType MessageType => EMessageType.IdAssigning;
} }
} }
@@ -1,21 +1,27 @@
using System; using System;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using mROA.Implementation.Attributes;
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
namespace mROA.Implementation namespace mROA.Implementation
{ {
public class NetworkMessage public interface INetworkMessage
{
[SerializationIgnore]
public EMessageType MessageType { get; }
}
public class NetworkMessageHeader
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
[JsonConverter(typeof(JsonStringEnumConverter))] [JsonConverter(typeof(JsonStringEnumConverter))]
public MessageType SchemaId { get; set; } public EMessageType EMessageType { get; set; }
public byte[] Data { get; set; } public byte[] Data { get; set; }
} }
public enum MessageType public enum EMessageType
{ {
Unknown, Unknown,
FinishedCommandExecution, FinishedCommandExecution,
@@ -23,6 +29,7 @@ namespace mROA.Implementation
CallRequest, CallRequest,
IdAssigning, IdAssigning,
CancelRequest, CancelRequest,
EventRequest EventRequest,
ClientRecovery
} }
} }
@@ -11,8 +11,8 @@ namespace mROA.Implementation
{ {
private const int BufferSize = ushort.MaxValue; private const int BufferSize = ushort.MaxValue;
private readonly Memory<byte> _buffer = new byte[BufferSize]; private readonly Memory<byte> _buffer = new byte[BufferSize];
private readonly List<NetworkMessage> _messageBuffer = new(128); private readonly List<NetworkMessageHeader> _messageBuffer = new(128);
private Task<NetworkMessage>? _currentReceiving; private Task<NetworkMessageHeader>? _currentReceiving;
private ISerializationToolkit? _serialization; private ISerializationToolkit? _serialization;
public int ConnectionId { get; set; } public int ConnectionId { get; set; }
public Stream? BaseStream { get; set; } public Stream? BaseStream { get; set; }
@@ -31,14 +31,14 @@ namespace mROA.Implementation
} }
} }
public Task<NetworkMessage> GetNextMessageReceiving() public Task<NetworkMessageHeader> GetNextMessageReceiving()
{ {
if (_currentReceiving != null) return _currentReceiving; if (_currentReceiving != null) return _currentReceiving;
_currentReceiving = Task.Run(async () => await GetNextMessage()); _currentReceiving = Task.Run(async () => await GetNextMessage());
return _currentReceiving; return _currentReceiving;
} }
public async Task PostMessage(NetworkMessage message) public async Task PostMessage(NetworkMessageHeader messageHeader)
{ {
if (BaseStream == null) if (BaseStream == null)
throw new NullReferenceException("BaseStream is null"); throw new NullReferenceException("BaseStream is null");
@@ -49,26 +49,26 @@ namespace mROA.Implementation
// Console.WriteLine("Sending {0}", JsonSerializer.Serialize(message)); // Console.WriteLine("Sending {0}", JsonSerializer.Serialize(message));
var rawMessage = _serialization.Serialize(message); var rawMessage = _serialization.Serialize(messageHeader);
var header = BitConverter.GetBytes((ushort)rawMessage.Length).AsMemory(0, sizeof(ushort)); var header = BitConverter.GetBytes((ushort)rawMessage.Length).AsMemory(0, sizeof(ushort));
await BaseStream.WriteAsync(header); await BaseStream.WriteAsync(header);
await BaseStream.WriteAsync(rawMessage); await BaseStream.WriteAsync(rawMessage);
} }
public void HandleMessage(NetworkMessage message) public void HandleMessage(NetworkMessageHeader messageHeader)
{ {
_messageBuffer.Remove(message); _messageBuffer.Remove(messageHeader);
} }
public NetworkMessage[] UnhandledMessages => _messageBuffer.ToArray(); public NetworkMessageHeader[] UnhandledMessages => _messageBuffer.ToArray();
public NetworkMessage? FirstByFilter(Predicate<NetworkMessage> predicate) public NetworkMessageHeader? FirstByFilter(Predicate<NetworkMessageHeader> predicate)
{ {
return _messageBuffer.FirstOrDefault(m => predicate(m)); return _messageBuffer.FirstOrDefault(m => predicate(m));
} }
private async Task<NetworkMessage> GetNextMessage() private async Task<NetworkMessageHeader> GetNextMessage()
{ {
if (BaseStream == null) if (BaseStream == null)
throw new NullReferenceException("BaseStream is null"); throw new NullReferenceException("BaseStream is null");
@@ -88,7 +88,7 @@ namespace mROA.Implementation
// Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len])); // Console.WriteLine("Receiving {0}", Encoding.Default.GetString(_buffer[..len]));
var message = _serialization.Deserialize<NetworkMessage>(localSpan.Span); var message = _serialization.Deserialize<NetworkMessageHeader>(localSpan.Span);
#if TRACE #if TRACE
Console.WriteLine($"{DateTime.Now.TimeOfDay} Received Message {message.Id} - {message.SchemaId}"); Console.WriteLine($"{DateTime.Now.TimeOfDay} Received Message {message.Id} - {message.SchemaId}");
TransmissionConfig.TotalTransmittedBytes += len; TransmissionConfig.TotalTransmittedBytes += len;
+8 -8
View File
@@ -56,24 +56,24 @@ namespace mROA.Implementation
CommandId = methodId, ObjectId = _identifier, Parameters = parameters CommandId = methodId, ObjectId = _identifier, Parameters = parameters
}; };
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request); await _representationModule.PostCallMessageAsync(request.Id, EMessageType.CallRequest, request);
var localTokenSource = new CancellationTokenSource(); var localTokenSource = new CancellationTokenSource();
var successResponse = var successResponse =
_representationModule.GetMessageAsync<FinalCommandExecution<T>>(request.Id, _representationModule.GetMessageAsync<FinalCommandExecution<T>>(request.Id,
MessageType.FinishedCommandExecution, EMessageType.FinishedCommandExecution,
localTokenSource.Token); localTokenSource.Token);
var errorResponse = var errorResponse =
_representationModule.GetMessageAsync<ExceptionCommandExecution>(requestId: request.Id, _representationModule.GetMessageAsync<ExceptionCommandExecution>(requestId: request.Id,
MessageType.ExceptionCommandExecution, localTokenSource.Token); EMessageType.ExceptionCommandExecution, localTokenSource.Token);
cancellationToken.Register(async () => cancellationToken.Register(async () =>
{ {
#if TRACE #if TRACE
Console.WriteLine("Cancelling task"); Console.WriteLine("Cancelling task");
#endif #endif
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest, await _representationModule.PostCallMessageAsync(request.Id, EMessageType.CancelRequest,
new CancelRequest new CancelRequest
{ {
Id = request.Id Id = request.Id
@@ -103,24 +103,24 @@ namespace mROA.Implementation
{ {
CommandId = methodId, ObjectId = _identifier, Parameters = parameters CommandId = methodId, ObjectId = _identifier, Parameters = parameters
}; };
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CallRequest, request); await _representationModule.PostCallMessageAsync(request.Id, EMessageType.CallRequest, request);
var localTokenSource = new CancellationTokenSource(); var localTokenSource = new CancellationTokenSource();
var successResponse = var successResponse =
_representationModule.GetMessageAsync<FinalCommandExecution>(request.Id, _representationModule.GetMessageAsync<FinalCommandExecution>(request.Id,
MessageType.FinishedCommandExecution, EMessageType.FinishedCommandExecution,
localTokenSource.Token); localTokenSource.Token);
var errorResponse = var errorResponse =
_representationModule.GetMessageAsync<ExceptionCommandExecution>(requestId: request.Id, _representationModule.GetMessageAsync<ExceptionCommandExecution>(requestId: request.Id,
MessageType.ExceptionCommandExecution, localTokenSource.Token); EMessageType.ExceptionCommandExecution, localTokenSource.Token);
cancellationToken.Register(async () => cancellationToken.Register(async () =>
{ {
#if TRACE #if TRACE
Console.WriteLine("Cancelling task"); Console.WriteLine("Cancelling task");
#endif #endif
await _representationModule.PostCallMessageAsync(request.Id, MessageType.CancelRequest, await _representationModule.PostCallMessageAsync(request.Id, EMessageType.CancelRequest,
new CancelRequest new CancelRequest
{ {
Id = request.Id Id = request.Id
+14 -14
View File
@@ -28,7 +28,7 @@ namespace mROA.Implementation
public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized")) public int Id => (_interaction ?? throw new NullReferenceException("Interaction is not initialized"))
.ConnectionId; .ConnectionId;
public async Task<T> GetMessageAsync<T>(Guid? requestId, MessageType? messageType, public async Task<T> GetMessageAsync<T>(Guid? requestId, EMessageType? messageType,
CancellationToken token = default) CancellationToken token = default)
{ {
if (_serialization == null) if (_serialization == null)
@@ -38,7 +38,7 @@ namespace mROA.Implementation
return _serialization.Deserialize<T>(rawMessage)!; return _serialization.Deserialize<T>(rawMessage)!;
} }
public T GetMessage<T>(Guid? requestId = null, MessageType? messageType = null) public T GetMessage<T>(Guid? requestId = null, EMessageType? messageType = null)
{ {
if (_serialization == null) if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized"); throw new NullReferenceException("Serialization toolkit is not initialized");
@@ -47,7 +47,7 @@ namespace mROA.Implementation
return _serialization.Deserialize<T>(rawMessage)!; return _serialization.Deserialize<T>(rawMessage)!;
} }
public async Task<byte[]> GetRawMessage(Guid? requestId = null, MessageType? messageType = null, public async Task<byte[]> GetRawMessage(Guid? requestId = null, EMessageType? messageType = null,
CancellationToken token = default) CancellationToken token = default)
{ {
if (_interaction == null) if (_interaction == null)
@@ -56,7 +56,7 @@ namespace mROA.Implementation
var fromBuffer = var fromBuffer =
_interaction.FirstByFilter(message => _interaction.FirstByFilter(message =>
(requestId is null || message.Id == requestId) && (requestId is null || message.Id == requestId) &&
(messageType is null || message.SchemaId == messageType)); (messageType is null || message.EMessageType == messageType));
if (fromBuffer == null) if (fromBuffer == null)
{ {
@@ -64,7 +64,7 @@ namespace mROA.Implementation
{ {
var message = await _interaction.GetNextMessageReceiving(); var message = await _interaction.GetNextMessageReceiving();
if ((requestId is not null && message.Id != requestId) || if ((requestId is not null && message.Id != requestId) ||
(messageType is not null && message.SchemaId != messageType)) (messageType is not null && message.EMessageType != messageType))
continue; continue;
_interaction.HandleMessage(message); _interaction.HandleMessage(message);
@@ -81,12 +81,12 @@ namespace mROA.Implementation
return fromBuffer.Data; return fromBuffer.Data;
} }
public async Task PostCallMessageAsync<T>(Guid id, MessageType messageType, T payload) where T : notnull public async Task PostCallMessageAsync<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull
{ {
await PostCallMessageAsync(id, messageType, payload, typeof(T)); await PostCallMessageAsync(id, eMessageType, payload, typeof(T));
} }
public async Task PostCallMessageAsync(Guid id, MessageType messageType, object payload, Type payloadType) public async Task PostCallMessageAsync(Guid id, EMessageType eMessageType, object payload, Type payloadType)
{ {
if (_interaction == null) if (_interaction == null)
throw new NullReferenceException("Interaction toolkit is not initialized"); throw new NullReferenceException("Interaction toolkit is not initialized");
@@ -97,18 +97,18 @@ namespace mROA.Implementation
#endif #endif
var serialized = _serialization.Serialize(payload, payloadType); var serialized = _serialization.Serialize(payload, payloadType);
await _interaction.PostMessage(new NetworkMessage await _interaction.PostMessage(new NetworkMessageHeader
{ Id = id, SchemaId = messageType, Data = serialized }); { Id = id, EMessageType = eMessageType, Data = serialized });
} }
public void PostCallMessage<T>(Guid id, MessageType messageType, T payload) where T : notnull public void PostCallMessage<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull
{ {
PostCallMessageAsync(id, messageType, payload).GetAwaiter().GetResult(); PostCallMessageAsync(id, eMessageType, payload).GetAwaiter().GetResult();
} }
public void PostCallMessage(Guid id, MessageType messageType, object payload, Type payloadType) public void PostCallMessage(Guid id, EMessageType eMessageType, object payload, Type payloadType)
{ {
PostCallMessageAsync(id, messageType, payload, payloadType).GetAwaiter().GetResult(); PostCallMessageAsync(id, eMessageType, payload, payloadType).GetAwaiter().GetResult();
} }
} }
} }