Client udp service

This commit is contained in:
2025-05-03 21:43:02 +03:00
parent f62a4943b9
commit 4f18f41389
11 changed files with 143 additions and 15 deletions
+5
View File
@@ -10,6 +10,11 @@ namespace Example.Backend
{ {
public string Name; public string Name;
public async Task SomeoneIsApproaching(string humanName)
{
Console.WriteLine(humanName + " is approaching");
}
public void OnPrintExternal(IPage p0, RequestContext ro) public void OnPrintExternal(IPage p0, RequestContext ro)
{ {
OnPrint?.Invoke(p0, ro); OnPrint?.Invoke(p0, ro);
+5
View File
@@ -8,6 +8,11 @@ namespace Example.Frontend
{ {
public class ClientBasedPrinter : IPrinter public class ClientBasedPrinter : IPrinter
{ {
public Task SomeoneIsApproaching(string humanName)
{
return Task.CompletedTask;
}
public void OnPrintExternal(IPage p0, RequestContext ro) public void OnPrintExternal(IPage p0, RequestContext ro)
{ {
} }
+2
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Net; using System.Net;
using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -120,6 +121,7 @@ class Program
DemoCheck.Show(); DemoCheck.Show();
Console.ReadKey(); Console.ReadKey();
// //
// const int iterations = 10000; // const int iterations = 10000;
// var timer = Stopwatch.StartNew(); // var timer = Stopwatch.StartNew();
+2
View File
@@ -13,5 +13,7 @@ namespace Example.Shared
string GetName(); string GetName();
Task<IPage> Print(string text, bool someParameter, RequestContext context, CancellationToken cancellationToken); Task<IPage> Print(string text, bool someParameter, RequestContext context, CancellationToken cancellationToken);
event Action<IPage, RequestContext> OnPrint; event Action<IPage, RequestContext> OnPrint;
[Untrusted]
Task SomeoneIsApproaching(string humanName);
} }
} }
+28 -14
View File
@@ -291,23 +291,38 @@ namespace mROA.Codegen
$"{method.ReturnType.ToUnityString()} {method.Name}({string.Join(", ", method.Parameters.Select(ToFullString))}){{"); $"{method.ReturnType.ToUnityString()} {method.Name}({string.Join(", ", method.Parameters.Select(ToFullString))}){{");
var isUntrusted = method.GetAttributes().Any(i => i.AttributeClass.Name == "UntrustedAttribute");
var prefix = isAsync ? "await " : ""; var prefix = isAsync ? "await " : "";
var postfix = !isAsync ? isVoid ? ".Wait()" : ".GetAwaiter().GetResult()" : ""; var postfix = !isAsync ? isVoid ? ".Wait()" : ".GetAwaiter().GetResult()" : "";
var parameterLink = isParametrized var parameterLink = isParametrized
? ", new System.Object[] { " + string.Join(", ", parameters.Select(i => i.Name)) + " }" ? ", new System.Object[] { " + string.Join(", ", parameters.Select(i => i.Name)) + " }"
: string.Empty; : string.Empty;
var tokenInsert = isAsync && method.Parameters.FirstOrDefault(i => i.Type.Name == "CancellationToken") is
{ } tokenSymbol
? ", cancellationToken : " + tokenSymbol.Name
: string.Empty;
var caller = isVoid
? $"CallAsync({index}{parameterLink}{tokenInsert})"
: isAsync
? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>({index}{parameterLink}{tokenInsert})"
: $"GetResultAsync<{ToFullString(method.ReturnType)}>({index}{parameterLink}{tokenInsert})";
if (!isVoid) string caller;
prefix = "return " + prefix;
if (isUntrusted)
{
caller = $"CallUntrustedAsync({index}{parameterLink})";
}
else
{
var tokenInsert = isAsync &&
method.Parameters.FirstOrDefault(i => i.Type.Name == "CancellationToken") is
{ } tokenSymbol
? ", cancellationToken : " + tokenSymbol.Name
: string.Empty;
caller = isVoid
? $"CallAsync({index}{parameterLink}{tokenInsert})"
: isAsync
? $"GetResultAsync<{ExtractTaskType(method.ReturnType)}>({index}{parameterLink}{tokenInsert})"
: $"GetResultAsync<{ToFullString(method.ReturnType)}>({index}{parameterLink}{tokenInsert})";
if (!isVoid)
prefix = "return " + prefix;
}
sb.AppendLine("\t\t\t" + prefix + caller + postfix + ";"); sb.AppendLine("\t\t\t" + prefix + caller + postfix + ";");
@@ -482,8 +497,8 @@ namespace mROA.Codegen
var parameterTypes = string.Join(", ", var parameterTypes = string.Join(", ",
$"{string.Join(", ", method.Parameters.Select(p => "typeof(" + p.Type.ToUnityString() + ")"))}"); $"{string.Join(", ", method.Parameters.Select(p => "typeof(" + p.Type.ToUnityString() + ")"))}");
var parameterInserts = string.Join(", ", var parameterInserts = string.Join(", ",
method.Parameters.Select( method.Parameters.Select(p =>
p => Caster(p.Type, "parameters[" + method.Parameters.IndexOf(p) + "]"))); Caster(p.Type, "parameters[" + method.Parameters.IndexOf(p) + "]")));
var invokerTemplate = (TemplateDocument)_methodInvokerOriginal.Clone(); var invokerTemplate = (TemplateDocument)_methodInvokerOriginal.Clone();
invokerTemplate.AddDefine("isVoid", "false"); invokerTemplate.AddDefine("isVoid", "false");
@@ -612,7 +627,6 @@ namespace mROA.Codegen
return parts.ToUnityString(); return parts.ToUnityString();
return type.ToDisplayString(); return type.ToDisplayString();
} }
public static string ToUnityString(this IParameterSymbol parameter) public static string ToUnityString(this IParameterSymbol parameter)
+1
View File
@@ -19,6 +19,7 @@ namespace mROA.Abstract
Task PostCallMessageAsync<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull; Task PostCallMessageAsync<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull;
void PostCallMessage<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull; void PostCallMessage<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull;
Task PostCallMessageUntrustedAsync<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull;
void PostCallMessage(Guid id, EMessageType eMessageType, object payload, Type payloadType); void PostCallMessage(Guid id, EMessageType eMessageType, object payload, Type payloadType);
} }
} }
@@ -0,0 +1,11 @@
using System;
using System.Net;
using System.Threading.Tasks;
namespace mROA.Abstract
{
public interface IUntrustedInteractionModule : IInjectableModule, IDisposable
{
Task Start(IPEndPoint endpoint);
}
}
@@ -0,0 +1,8 @@
using System;
namespace mROA.Implementation.Attributes
{
public class UntrustedAttribute : Attribute
{
}
}
+9
View File
@@ -137,6 +137,15 @@ namespace mROA.Implementation
} }
} }
protected async Task CallUntrustedAsync(int methodId, object?[]? parameters = null)
{
var request = new DefaultCallRequest
{
CommandId = methodId, ObjectId = _identifier, Parameters = parameters
};
await _representationModule.PostCallMessageUntrustedAsync(request.Id, EMessageType.CallRequest, request);
}
public override string ToString() public override string ToString()
{ {
return _identifier.ToString(); return _identifier.ToString();
@@ -95,6 +95,13 @@ namespace mROA.Implementation
PostCallMessageAsync(id, eMessageType, payload).GetAwaiter().GetResult(); PostCallMessageAsync(id, eMessageType, payload).GetAwaiter().GetResult();
} }
public async Task PostCallMessageUntrustedAsync<T>(Guid id, EMessageType eMessageType, T payload) where T : notnull
{
var serialized = _serialization.Serialize(payload, typeof(T));
await _interaction.PostMessageUntrustedAsync(new NetworkMessageHeader
{ Id = id, MessageType = eMessageType, Data = serialized });
}
public void PostCallMessage(Guid id, EMessageType eMessageType, object payload, Type payloadType) public void PostCallMessage(Guid id, EMessageType eMessageType, object payload, Type payloadType)
{ {
PostCallMessageAsync(id, eMessageType, payload, payloadType).GetAwaiter().GetResult(); PostCallMessageAsync(id, eMessageType, payload, payloadType).GetAwaiter().GetResult();
@@ -0,0 +1,64 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using mROA.Abstract;
namespace mROA.Implementation
{
public class UdpUntrustedInteraction : IUntrustedInteractionModule
{
private ISerializationToolkit _serializationToolkit;
private IChannelInteractionModule _channelInteractionModule;
private CancellationTokenSource _tokenSource = new CancellationTokenSource();
public void Dispose()
{
_tokenSource.Cancel();
}
public Task Start(IPEndPoint endpoint)
{
return Task.Run(() =>
{
var client = new UdpClient();
client.Connect(endpoint);
Listening(client, _tokenSource.Token);
Posting(client, _tokenSource.Token);
}, _tokenSource.Token);
}
private async Task Listening(UdpClient udpClient, CancellationToken token)
{
var writer = _channelInteractionModule.ReceiveChanel.Writer;
while (token.IsCancellationRequested == false)
{
var message = new Memory<byte>((await udpClient.ReceiveAsync()).Buffer);
var parsed = _serializationToolkit.Deserialize<NetworkMessageHeader>(message.Span)!;
await writer.WriteAsync(parsed, token);
}
}
private async Task Posting(UdpClient udpClient, CancellationToken token)
{
await foreach (var post in _channelInteractionModule.UntrustedPostChanel.ReadAllAsync(token))
{
var serialized = _serializationToolkit.Serialize(post);
await udpClient.SendAsync(serialized, serialized.Length);
}
}
public void Inject<T>(T dependency)
{
switch (dependency)
{
case IChannelInteractionModule channelModule:
_channelInteractionModule = channelModule;
break;
case ISerializationToolkit serializationToolkit:
_serializationToolkit = serializationToolkit;
break;
}
}
}
}