зеркало из https://github.com/microsoft/AMBROSIA.git
Merge branch 'master' of https://github.com/Microsoft/AMBROSIA
This commit is contained in:
Коммит
19733d0e00
|
@ -1,5 +1,5 @@
|
|||
using Ambrosia;
|
||||
using IClient;
|
||||
using IClient1;
|
||||
using IServer;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
using System;
|
||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||
namespace Client1
|
||||
{
|
||||
[DataContract]
|
||||
class Client1 : Immortal<IClientProxy>, IClient.IClient
|
||||
class Client1 : Immortal<IClient1Proxy>, IClient1.IClient1
|
||||
{
|
||||
[DataMember]
|
||||
private string _serverName;
|
||||
|
@ -50,7 +50,7 @@ namespace Client1
|
|||
string clientInstanceName = "client1";
|
||||
string serverInstanceName = "server1";
|
||||
|
||||
using (var c = AmbrosiaFactory.Deploy<IClient.IClient>(clientInstanceName, new Client1(serverInstanceName), receivePort, sendPort))
|
||||
using (var c = AmbrosiaFactory.Deploy<IClient1.IClient1>(clientInstanceName, new Client1(serverInstanceName), receivePort, sendPort))
|
||||
{
|
||||
finishedTokenQ.DequeueAsync().Wait();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AmbrosiaLibCS" Version="2018.12.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GeneratedSourceFiles\Client2Interfaces\latest\Client2Interfaces.csproj" />
|
||||
<ProjectReference Include="..\GeneratedSourceFiles\ServerInterfaces\latest\ServerInterfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Ambrosia;
|
||||
using IClient2;
|
||||
using IServer;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
|
||||
namespace Client2
|
||||
{
|
||||
[DataContract]
|
||||
class Client2 : Immortal<IClient2Proxy>, IClient2.IClient2
|
||||
{
|
||||
[DataMember]
|
||||
private string _serverName;
|
||||
|
||||
[DataMember]
|
||||
private IServerProxy _server;
|
||||
|
||||
public Client2(string serverName)
|
||||
{
|
||||
_serverName = serverName;
|
||||
}
|
||||
|
||||
public void IngressKeyboardInput(string input)
|
||||
{
|
||||
thisProxy.ReceiveKeyboardInputFork(input);
|
||||
}
|
||||
|
||||
public async Task ReceiveKeyboardInputAsync(string input)
|
||||
{
|
||||
await thisProxy.SendMessageAsync(input);
|
||||
}
|
||||
|
||||
public async Task SendMessageAsync(string message)
|
||||
{
|
||||
Console.WriteLine("Sending message to server: " + message);
|
||||
int numMessages = await _server.ReceiveMessageAsync(message);
|
||||
Console.WriteLine("Sent message to server! Server has received " + numMessages + " messages.");
|
||||
}
|
||||
|
||||
protected override async Task<bool> OnFirstStart()
|
||||
{
|
||||
_server = GetProxy<IServerProxy>(_serverName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class Program
|
||||
{
|
||||
public static AsyncQueue<int> finishedTokenQ;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
finishedTokenQ = new AsyncQueue<int>();
|
||||
|
||||
int receivePort = 1001;
|
||||
int sendPort = 1000;
|
||||
string clientInstanceName = "client2";
|
||||
string serverInstanceName = "server1";
|
||||
|
||||
Client2 client = new Client2(serverInstanceName);
|
||||
using (var c = AmbrosiaFactory.Deploy<IClient2.IClient2>(clientInstanceName, client, receivePort, sendPort))
|
||||
{
|
||||
while (finishedTokenQ.IsEmpty)
|
||||
{
|
||||
Console.Write("Enter a message (hit ENTER to send): ");
|
||||
string input = Console.ReadLine();
|
||||
client.IngressKeyboardInput(input);
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
finishedTokenQ.DequeueAsync().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,8 +14,11 @@ Write-Host "Using variant of CodeGen.exe: $env:AMBVARIANT"
|
|||
|
||||
Write-Host "Executing codegen command: dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a=ServerAPI\bin\$env:AMBVARIANT\IServer.dll -o=ServerInterfaces -f=netcoreapp2.0 -b=CodeGenDependencies\netcoreapp2.0"
|
||||
|
||||
Write-Host "Executing codegen command: dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a=IClient\bin\$env:AMBVARIANT\IClient.dll -o=Client1Interfaces -f=netcoreapp2.0 -b=CodeGenDependencies\netcoreapp2.0"
|
||||
Write-Host "Executing codegen command: dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a=IClient1\bin\$env:AMBVARIANT\IClient1.dll -o=Client1Interfaces -f=netcoreapp2.0 -b=CodeGenDependencies\netcoreapp2.0"
|
||||
|
||||
Write-Host "Executing codegen command: dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a=IClient2\bin\$env:AMBVARIANT\IClient2.dll -o=Client2Interfaces -f=netcoreapp2.0 -b=CodeGenDependencies\netcoreapp2.0"
|
||||
|
||||
# Generate the assemblies, assumes an .exe which is created by a .Net Framework build:
|
||||
& dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a="ServerAPI\bin\$env:AMBVARIANT\IServer.dll" -o=ServerInterfaces -f="netcoreapp2.0" -b="CodeGenDependencies\netcoreapp2.0"
|
||||
& dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a="IClient\bin\$env:AMBVARIANT\IClient.dll" -o=Client1Interfaces -f="netcoreapp2.0" -b="CodeGenDependencies\netcoreapp2.0"
|
||||
& dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a="IClient1\bin\$env:AMBVARIANT\IClient1.dll" -o=Client1Interfaces -f="netcoreapp2.0" -b="CodeGenDependencies\netcoreapp2.0"
|
||||
& dotnet $ambrosiaPath\Clients\CSharp\AmbrosiaCS\bin\$env:AMBVARIANT\AmbrosiaCS.dll CodeGen -a="IClient2\bin\$env:AMBVARIANT\IClient2.dll" -o=Client2Interfaces -f="netcoreapp2.0" -b="CodeGenDependencies\netcoreapp2.0"
|
|
@ -6,29 +6,29 @@ using Ambrosia;
|
|||
using static Ambrosia.StreamCommunicator;
|
||||
using LocalAmbrosiaRuntime;
|
||||
|
||||
namespace IClient
|
||||
namespace IClient1
|
||||
{
|
||||
/// <summary>
|
||||
/// This class runs in the process of the object that implements the interface IClient
|
||||
/// This class runs in the process of the object that implements the interface IClient1
|
||||
/// and communicates with the local Ambrosia runtime.
|
||||
/// It is instantiated in ImmortalFactory.CreateServer when a bootstrapper registers a container
|
||||
/// that supports the interface IClient.
|
||||
/// that supports the interface IClient1.
|
||||
/// </summary>
|
||||
class IClient_Dispatcher_Implementation : Immortal.Dispatcher
|
||||
class IClient1_Dispatcher_Implementation : Immortal.Dispatcher
|
||||
{
|
||||
private readonly IClient instance;
|
||||
private readonly IClient1 instance;
|
||||
private readonly ExceptionSerializer exceptionSerializer = new ExceptionSerializer(new List<Type>());
|
||||
|
||||
public IClient_Dispatcher_Implementation(Immortal z, ImmortalSerializerBase myImmortalSerializer, string serviceName, int receivePort, int sendPort, bool setupConnections)
|
||||
public IClient1_Dispatcher_Implementation(Immortal z, ImmortalSerializerBase myImmortalSerializer, string serviceName, int receivePort, int sendPort, bool setupConnections)
|
||||
: base(z, myImmortalSerializer, serviceName, receivePort, sendPort, setupConnections)
|
||||
{
|
||||
this.instance = (IClient) z;
|
||||
this.instance = (IClient1) z;
|
||||
}
|
||||
|
||||
public IClient_Dispatcher_Implementation(Immortal z, ImmortalSerializerBase myImmortalSerializer, string localAmbrosiaRuntime, Type newInterface, Type newImmortalType, int receivePort, int sendPort)
|
||||
public IClient1_Dispatcher_Implementation(Immortal z, ImmortalSerializerBase myImmortalSerializer, string localAmbrosiaRuntime, Type newInterface, Type newImmortalType, int receivePort, int sendPort)
|
||||
: base(z, myImmortalSerializer, localAmbrosiaRuntime, newInterface, newImmortalType, receivePort, sendPort)
|
||||
{
|
||||
this.instance = (IClient) z;
|
||||
this.instance = (IClient1) z;
|
||||
}
|
||||
|
||||
public override async Task<bool> DispatchToMethod(int methodId, RpcTypes.RpcType rpcType, string senderOfRPC, long sequenceNumber, byte[] buffer, int cursor)
|
|
@ -10,7 +10,7 @@ using System.Xml;
|
|||
|
||||
using Ambrosia;
|
||||
using static Ambrosia.StreamCommunicator;
|
||||
using IClient;
|
||||
using IClient1;
|
||||
|
||||
namespace Ambrosia
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ namespace Ambrosia
|
|||
{
|
||||
base.KnownTypes = new SerializableType[]
|
||||
{
|
||||
new SerializableType(typeof(IClientProxy_Implementation)),
|
||||
new SerializableType(typeof(IClient1Proxy_Implementation)),
|
||||
new SerializableType(this.GetType())
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,23 +4,23 @@ using Ambrosia;
|
|||
using System.Threading.Tasks;
|
||||
using static Ambrosia.StreamCommunicator;
|
||||
|
||||
namespace IClient
|
||||
namespace IClient1
|
||||
{
|
||||
/// <summary>
|
||||
// Generated from IClient by the proxy generation.
|
||||
// Generated from IClient1 by the proxy generation.
|
||||
// This is the API that any immortal implementing the interface must be a subtype of.
|
||||
/// </summary>
|
||||
public interface IClient
|
||||
public interface IClient1
|
||||
{
|
||||
Task SendMessageAsync(System.String p_0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
// Generated from IClient by the proxy generation.
|
||||
// Generated from IClient1 by the proxy generation.
|
||||
// This is the API that is used to call a immortal that implements
|
||||
/// </summary>
|
||||
[Ambrosia.InstanceProxy(typeof(IClient))]
|
||||
public interface IClientProxy
|
||||
[Ambrosia.InstanceProxy(typeof(IClient1))]
|
||||
public interface IClient1Proxy
|
||||
{
|
||||
Task SendMessageAsync(System.String p_0);
|
||||
void SendMessageFork(System.String p_0);
|
|
@ -6,24 +6,24 @@ using Ambrosia;
|
|||
using static Ambrosia.StreamCommunicator;
|
||||
|
||||
|
||||
namespace IClient
|
||||
namespace IClient1
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is the proxy that runs in the client's process and communicates with the local Ambrosia runtime.
|
||||
/// It runs within the client's process, so it is generated in the language that the client is using.
|
||||
/// It is returned from ImmortalFactory.CreateClient when a client requests a container that supports the interface IClientProxy.
|
||||
/// It is returned from ImmortalFactory.CreateClient when a client requests a container that supports the interface IClient1Proxy.
|
||||
/// </summary>
|
||||
[System.Runtime.Serialization.DataContract]
|
||||
public class IClientProxy_Implementation : Immortal.InstanceProxy, IClientProxy
|
||||
public class IClient1Proxy_Implementation : Immortal.InstanceProxy, IClient1Proxy
|
||||
{
|
||||
|
||||
public IClientProxy_Implementation(string remoteAmbrosiaRuntime, bool attachNeeded)
|
||||
public IClient1Proxy_Implementation(string remoteAmbrosiaRuntime, bool attachNeeded)
|
||||
: base(remoteAmbrosiaRuntime, attachNeeded)
|
||||
{
|
||||
}
|
||||
|
||||
async Task
|
||||
IClientProxy.SendMessageAsync(System.String p_0)
|
||||
IClient1Proxy.SendMessageAsync(System.String p_0)
|
||||
{
|
||||
await SendMessageAsync(p_0);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ wp.curLength += arg0Bytes.Length;
|
|||
return;
|
||||
}
|
||||
|
||||
void IClientProxy.SendMessageFork(System.String p_0)
|
||||
void IClient1Proxy.SendMessageFork(System.String p_0)
|
||||
{
|
||||
SerializableTaskCompletionSource rpcTask;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AmbrosiaLibCS" Version="2018.11.30.1" />
|
||||
<PackageReference Include="Mono.Options.Core" Version="1.0.0" />
|
||||
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.9.0" />
|
||||
<PackageReference Update="Microsoft.NETCore.App=" Version="2.0.0=" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,125 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ambrosia;
|
||||
using static Ambrosia.StreamCommunicator;
|
||||
using LocalAmbrosiaRuntime;
|
||||
|
||||
namespace IClient2
|
||||
{
|
||||
/// <summary>
|
||||
/// This class runs in the process of the object that implements the interface IClient2
|
||||
/// and communicates with the local Ambrosia runtime.
|
||||
/// It is instantiated in ImmortalFactory.CreateServer when a bootstrapper registers a container
|
||||
/// that supports the interface IClient2.
|
||||
/// </summary>
|
||||
class IClient2_Dispatcher_Implementation : Immortal.Dispatcher
|
||||
{
|
||||
private readonly IClient2 instance;
|
||||
private readonly ExceptionSerializer exceptionSerializer = new ExceptionSerializer(new List<Type>());
|
||||
|
||||
public IClient2_Dispatcher_Implementation(Immortal z, ImmortalSerializerBase myImmortalSerializer, string serviceName, int receivePort, int sendPort, bool setupConnections)
|
||||
: base(z, myImmortalSerializer, serviceName, receivePort, sendPort, setupConnections)
|
||||
{
|
||||
this.instance = (IClient2) z;
|
||||
}
|
||||
|
||||
public IClient2_Dispatcher_Implementation(Immortal z, ImmortalSerializerBase myImmortalSerializer, string localAmbrosiaRuntime, Type newInterface, Type newImmortalType, int receivePort, int sendPort)
|
||||
: base(z, myImmortalSerializer, localAmbrosiaRuntime, newInterface, newImmortalType, receivePort, sendPort)
|
||||
{
|
||||
this.instance = (IClient2) z;
|
||||
}
|
||||
|
||||
public override async Task<bool> DispatchToMethod(int methodId, RpcTypes.RpcType rpcType, string senderOfRPC, long sequenceNumber, byte[] buffer, int cursor)
|
||||
{
|
||||
switch (methodId)
|
||||
{
|
||||
case 0:
|
||||
// Entry point
|
||||
this.EntryPoint();
|
||||
break;
|
||||
case 1:
|
||||
// SendMessageAsync
|
||||
{
|
||||
// deserialize arguments
|
||||
|
||||
// arg0: System.String
|
||||
var p_0_ValueLength = buffer.ReadBufferedInt(cursor);
|
||||
cursor += IntSize(p_0_ValueLength);
|
||||
var p_0_ValueBuffer = new byte[p_0_ValueLength];
|
||||
Buffer.BlockCopy(buffer, cursor, p_0_ValueBuffer, 0, p_0_ValueLength);
|
||||
cursor += p_0_ValueLength;
|
||||
var p_0 = Ambrosia.BinarySerializer.Deserialize<System.String>(p_0_ValueBuffer);
|
||||
|
||||
// call the method
|
||||
byte[] argExBytes = null;
|
||||
int argExSize = 0;
|
||||
Exception currEx = null;
|
||||
int arg1Size = 0;
|
||||
byte[] arg1Bytes = null;
|
||||
|
||||
try
|
||||
{
|
||||
await this.instance.SendMessageAsync(p_0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
currEx = ex;
|
||||
}
|
||||
|
||||
if (!rpcType.IsFireAndForget())
|
||||
{
|
||||
// serialize result and send it back (there isn't one)
|
||||
arg1Size = 0;
|
||||
var wp = this.StartRPC_ReturnValue(senderOfRPC, sequenceNumber, currEx == null ? arg1Size : argExSize, currEx == null ? ReturnValueTypes.EmptyReturnValue : ReturnValueTypes.Exception);
|
||||
|
||||
this.ReleaseBufferAndSend();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// ReceiveKeyboardInputAsync
|
||||
{
|
||||
// deserialize arguments
|
||||
|
||||
// arg0: System.String
|
||||
var p_0_ValueLength = buffer.ReadBufferedInt(cursor);
|
||||
cursor += IntSize(p_0_ValueLength);
|
||||
var p_0_ValueBuffer = new byte[p_0_ValueLength];
|
||||
Buffer.BlockCopy(buffer, cursor, p_0_ValueBuffer, 0, p_0_ValueLength);
|
||||
cursor += p_0_ValueLength;
|
||||
var p_0 = Ambrosia.BinarySerializer.Deserialize<System.String>(p_0_ValueBuffer);
|
||||
|
||||
// call the method
|
||||
byte[] argExBytes = null;
|
||||
int argExSize = 0;
|
||||
Exception currEx = null;
|
||||
int arg1Size = 0;
|
||||
byte[] arg1Bytes = null;
|
||||
|
||||
try
|
||||
{
|
||||
await this.instance.ReceiveKeyboardInputAsync(p_0);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
currEx = ex;
|
||||
}
|
||||
|
||||
if (!rpcType.IsFireAndForget())
|
||||
{
|
||||
// serialize result and send it back (there isn't one)
|
||||
arg1Size = 0;
|
||||
var wp = this.StartRPC_ReturnValue(senderOfRPC, sequenceNumber, currEx == null ? arg1Size : argExSize, currEx == null ? ReturnValueTypes.EmptyReturnValue : ReturnValueTypes.Exception);
|
||||
|
||||
this.ReleaseBufferAndSend();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Dataflow;
|
||||
using System.Xml;
|
||||
|
||||
using Ambrosia;
|
||||
using static Ambrosia.StreamCommunicator;
|
||||
using IClient2;
|
||||
|
||||
namespace Ambrosia
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is the serializer that supports serialization of a Immortal and has the generated classes as a known types
|
||||
/// </summary>]
|
||||
public class ImmortalSerializer : ImmortalSerializerBase
|
||||
{
|
||||
public ImmortalSerializer()
|
||||
{
|
||||
base.KnownTypes = new SerializableType[]
|
||||
{
|
||||
new SerializableType(typeof(IClient2Proxy_Implementation)),
|
||||
new SerializableType(this.GetType())
|
||||
};
|
||||
}
|
||||
|
||||
public override long SerializeSize(Immortal c)
|
||||
{
|
||||
var serializer = new DataContractSerializer(c.GetType(), this.KnownTypes.Select(kt => kt.Type).ToArray());
|
||||
long retVal = -1;
|
||||
using (var countStream = new CountStream())
|
||||
{
|
||||
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(countStream))
|
||||
{
|
||||
serializer.WriteObject(writer, c);
|
||||
}
|
||||
retVal = countStream.Length;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public override void Serialize(Immortal c, Stream writeToStream)
|
||||
{
|
||||
// nned to create
|
||||
var serializer = new DataContractSerializer(c.GetType(), this.KnownTypes.Select(kt => kt.Type).ToArray());
|
||||
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(writeToStream))
|
||||
{
|
||||
serializer.WriteObject(writer, c);
|
||||
}
|
||||
}
|
||||
|
||||
public override Immortal Deserialize(Type runtimeType, Stream stream)
|
||||
{
|
||||
var serializer = new DataContractSerializer(runtimeType, this.KnownTypes.Select(kt => kt.Type).ToArray());
|
||||
using (var reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
|
||||
{
|
||||
return (Immortal)serializer.ReadObject(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface Empty : IEmpty
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
using System;
|
||||
using Ambrosia;
|
||||
using System.Threading.Tasks;
|
||||
using static Ambrosia.StreamCommunicator;
|
||||
|
||||
namespace IClient2
|
||||
{
|
||||
/// <summary>
|
||||
// Generated from IClient2 by the proxy generation.
|
||||
// This is the API that any immortal implementing the interface must be a subtype of.
|
||||
/// </summary>
|
||||
public interface IClient2
|
||||
{
|
||||
Task SendMessageAsync(System.String p_0);
|
||||
Task ReceiveKeyboardInputAsync(System.String p_0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
// Generated from IClient2 by the proxy generation.
|
||||
// This is the API that is used to call a immortal that implements
|
||||
/// </summary>
|
||||
[Ambrosia.InstanceProxy(typeof(IClient2))]
|
||||
public interface IClient2Proxy
|
||||
{
|
||||
Task SendMessageAsync(System.String p_0);
|
||||
void SendMessageFork(System.String p_0);
|
||||
void ReceiveKeyboardInputFork(System.String p_0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Dataflow;
|
||||
using Ambrosia;
|
||||
using static Ambrosia.StreamCommunicator;
|
||||
|
||||
|
||||
namespace IClient2
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is the proxy that runs in the client's process and communicates with the local Ambrosia runtime.
|
||||
/// It runs within the client's process, so it is generated in the language that the client is using.
|
||||
/// It is returned from ImmortalFactory.CreateClient when a client requests a container that supports the interface IClient2Proxy.
|
||||
/// </summary>
|
||||
[System.Runtime.Serialization.DataContract]
|
||||
public class IClient2Proxy_Implementation : Immortal.InstanceProxy, IClient2Proxy
|
||||
{
|
||||
|
||||
public IClient2Proxy_Implementation(string remoteAmbrosiaRuntime, bool attachNeeded)
|
||||
: base(remoteAmbrosiaRuntime, attachNeeded)
|
||||
{
|
||||
}
|
||||
|
||||
async Task
|
||||
IClient2Proxy.SendMessageAsync(System.String p_0)
|
||||
{
|
||||
await SendMessageAsync(p_0);
|
||||
}
|
||||
|
||||
async Task
|
||||
SendMessageAsync(System.String p_0)
|
||||
{
|
||||
SerializableTaskCompletionSource rpcTask;
|
||||
// Make call, wait for reply
|
||||
// Compute size of serialized arguments
|
||||
var totalArgSize = 0;
|
||||
|
||||
int arg0Size = 0;
|
||||
byte[] arg0Bytes = null;
|
||||
|
||||
// Argument 0
|
||||
arg0Bytes = Ambrosia.BinarySerializer.Serialize<System.String>(p_0);
|
||||
arg0Size = IntSize(arg0Bytes.Length) + arg0Bytes.Length;
|
||||
|
||||
totalArgSize += arg0Size;
|
||||
|
||||
var wp = this.StartRPC<object>(methodIdentifier: 1 /* method identifier for SendMessage */, lengthOfSerializedArguments: totalArgSize, taskToWaitFor: out rpcTask);
|
||||
var asyncContext = new AsyncContext { SequenceNumber = Immortal.CurrentSequenceNumber };
|
||||
|
||||
// Serialize arguments
|
||||
|
||||
|
||||
// Serialize arg0
|
||||
wp.curLength += wp.PageBytes.WriteInt(wp.curLength, arg0Bytes.Length);
|
||||
Buffer.BlockCopy(arg0Bytes, 0, wp.PageBytes, wp.curLength, arg0Bytes.Length);
|
||||
wp.curLength += arg0Bytes.Length;
|
||||
|
||||
|
||||
ReleaseBufferAndSend();
|
||||
|
||||
var taskToWaitFor = Immortal.CallCache.Data[asyncContext.SequenceNumber].GetAwaitableTaskWithAdditionalInfoAsync();
|
||||
var currentResult = await taskToWaitFor;
|
||||
|
||||
var isSaved = await Immortal.TrySaveContextContinuationAsync(currentResult);
|
||||
|
||||
if (isSaved)
|
||||
{
|
||||
taskToWaitFor = Immortal.CallCache.Data[asyncContext.SequenceNumber].GetAwaitableTaskWithAdditionalInfoAsync();
|
||||
currentResult = await taskToWaitFor;
|
||||
}
|
||||
|
||||
await Immortal.TryTakeCheckpointContinuationAsync(currentResult);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void IClient2Proxy.SendMessageFork(System.String p_0)
|
||||
{
|
||||
SerializableTaskCompletionSource rpcTask;
|
||||
|
||||
// Compute size of serialized arguments
|
||||
var totalArgSize = 0;
|
||||
|
||||
// Argument 0
|
||||
int arg0Size = 0;
|
||||
byte[] arg0Bytes = null;
|
||||
|
||||
arg0Bytes = Ambrosia.BinarySerializer.Serialize<System.String>(p_0);
|
||||
arg0Size = IntSize(arg0Bytes.Length) + arg0Bytes.Length;
|
||||
|
||||
totalArgSize += arg0Size;
|
||||
|
||||
var wp = this.StartRPC<object>(1 /* method identifier for SendMessage */, totalArgSize, out rpcTask, RpcTypes.RpcType.FireAndForget);
|
||||
|
||||
// Serialize arguments
|
||||
|
||||
|
||||
// Serialize arg0
|
||||
wp.curLength += wp.PageBytes.WriteInt(wp.curLength, arg0Bytes.Length);
|
||||
Buffer.BlockCopy(arg0Bytes, 0, wp.PageBytes, wp.curLength, arg0Bytes.Length);
|
||||
wp.curLength += arg0Bytes.Length;
|
||||
|
||||
|
||||
this.ReleaseBufferAndSend();
|
||||
return;
|
||||
}
|
||||
|
||||
private object
|
||||
SendMessage_ReturnValue(byte[] buffer, int cursor)
|
||||
{
|
||||
// buffer will be an empty byte array since the method SendMessage returns void
|
||||
// so nothing to read, just getting called is the signal to return to the client
|
||||
return this;
|
||||
}
|
||||
|
||||
void IClient2Proxy.ReceiveKeyboardInputFork(System.String p_0)
|
||||
{
|
||||
SerializableTaskCompletionSource rpcTask;
|
||||
|
||||
// Compute size of serialized arguments
|
||||
var totalArgSize = 0;
|
||||
|
||||
// Argument 0
|
||||
int arg0Size = 0;
|
||||
byte[] arg0Bytes = null;
|
||||
|
||||
arg0Bytes = Ambrosia.BinarySerializer.Serialize<System.String>(p_0);
|
||||
arg0Size = IntSize(arg0Bytes.Length) + arg0Bytes.Length;
|
||||
|
||||
totalArgSize += arg0Size;
|
||||
|
||||
var wp = this.StartRPC<object>(2 /* method identifier for ReceiveKeyboardInput */, totalArgSize, out rpcTask, RpcTypes.RpcType.Impulse);
|
||||
|
||||
// Serialize arguments
|
||||
|
||||
|
||||
// Serialize arg0
|
||||
wp.curLength += wp.PageBytes.WriteInt(wp.curLength, arg0Bytes.Length);
|
||||
Buffer.BlockCopy(arg0Bytes, 0, wp.PageBytes, wp.curLength, arg0Bytes.Length);
|
||||
wp.curLength += arg0Bytes.Length;
|
||||
|
||||
|
||||
this.ReleaseBufferAndSend();
|
||||
return;
|
||||
}
|
||||
|
||||
private object
|
||||
ReceiveKeyboardInput_ReturnValue(byte[] buffer, int cursor)
|
||||
{
|
||||
// buffer will be an empty byte array since the method ReceiveKeyboardInput returns void
|
||||
// so nothing to read, just getting called is the signal to return to the client
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerInterfaces", "Generat
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client1Interfaces", "GeneratedSourceFiles\Client1Interfaces\latest\Client1Interfaces.csproj", "{625A71B0-DA9E-467F-9744-A4344EA8B6E5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IClient", "IClient\IClient.csproj", "{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IClient2", "IClient2\IClient2.csproj", "{975C3389-6CE2-4905-BE58-57FCF29B5D31}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client2", "Client2\Client2.csproj", "{644D897D-1311-4073-9F0C-4197A9719E28}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client2Interfaces", "GeneratedSourceFiles\Client2Interfaces\latest\Client2Interfaces.csproj", "{6E5C78F0-B847-4C22-90B6-FAA96C013609}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IClient1", "IClient1\IClient1.csproj", "{8EFAD205-E2BF-46C0-B310-7D023210797F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -57,14 +63,38 @@ Global
|
|||
{625A71B0-DA9E-467F-9744-A4344EA8B6E5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{625A71B0-DA9E-467F-9744-A4344EA8B6E5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{625A71B0-DA9E-467F-9744-A4344EA8B6E5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Debug|x64.Build.0 = Debug|x64
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F07FF1A8-5617-4C43-B70A-14A4C8D57EDB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Debug|x64.Build.0 = Debug|x64
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{975C3389-6CE2-4905-BE58-57FCF29B5D31}.Release|x64.Build.0 = Release|Any CPU
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Debug|x64.Build.0 = Debug|x64
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{644D897D-1311-4073-9F0C-4197A9719E28}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{6E5C78F0-B847-4C22-90B6-FAA96C013609}.Release|x64.Build.0 = Release|Any CPU
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Debug|x64.Build.0 = Debug|x64
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Release|x64.ActiveCfg = Release|x64
|
||||
{8EFAD205-E2BF-46C0-B310-7D023210797F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using System;
|
||||
|
||||
namespace IClient
|
||||
namespace IClient1
|
||||
{
|
||||
public interface IClient
|
||||
public interface IClient1
|
||||
{
|
||||
void SendMessage(string message);
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>IClient1</AssemblyName>
|
||||
<RootNamespace>IClient1</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,13 @@
|
|||
using Ambrosia;
|
||||
using System;
|
||||
|
||||
namespace IClient2
|
||||
{
|
||||
public interface IClient2
|
||||
{
|
||||
void SendMessage(string message);
|
||||
|
||||
[ImpulseHandler]
|
||||
void ReceiveKeyboardInput(string message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AmbrosiaLibCS" Version="2018.12.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Загрузка…
Ссылка в новой задаче