ほんとにさわりだけ使ってみただけ、使用感はさほど変わってなかったけど、golang 使わずに C#だけで作ったら NamedPipe の使い方がよくわからず躓いたのでメモ代わりに記事を書く。
登場人物は3人、Target
と Client
と Server
Client
部分はほとんど 以前の記事(http://bamch0h.hatenablog.com/entry/2018/12/26/012124) と変わらない。
Server
部分は今回新規に書き起こした。 JsonRpc.Attach
の第二引数に RPC用のクラス Target
を指定することで、public メソッドを公開してくれるようだ。他にも色々公開の仕方があるみたいだけど、今回は割愛。
Server
の Attach
の次に、rpc.Completion
でタスクの終了を待っている。これをしないと、Client
が要求を投げるとServer
側がすぐさま終了してしまうようだった。応答を返して、Client
がちゃんとパイプをクローズしてくれるまで待つためにこの行を入れている。(これに気付くまでに結構時間が吸われたので辛かった。。。)
このプログラムを実行すると、1+2 の結果である 3
が表示される。
using System; using System.Threading.Tasks; using System.IO.Pipes; using StreamJsonRpc; namespace ConsoleApp5 { public class Target { public int Add(int a, int b) { return a + b; } } public class Client { public async Task Start(string pipename) { var stream = new NamedPipeClientStream(".", pipename, PipeDirection.InOut, PipeOptions.Asynchronous); stream.Connect(); using (var rpc = JsonRpc.Attach(stream)) { int ret = await rpc.InvokeAsync<int>("Add", 1, 2); Console.WriteLine(ret); } } } public class Server { public void Start(string pipename) { var stream = new NamedPipeServerStream(pipename, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); stream.WaitForConnection(); using (var rpc = JsonRpc.Attach(stream, new Target())) { rpc.Completion.Wait(); } } } class Program { static void Main(string[] args) { string pipename = "winiotestpipe"; var ts = Task.Run(() => new Client().Start(pipename)); var tc = Task.Run(() => new Server().Start(pipename)); Task.WhenAll(tc, ts).Wait(); Console.ReadLine(); } } }