昨日、UNIXドメインソケットをGoで使うサンプルを作成したがその際にパフォーマンス比較用に作成した名前付きパイプを使ってC#と通信する。
サーバーサイド(Go言語)
特筆するところはない。
package main import ( "log" winio "github.com/Microsoft/go-winio" ) var pipename = `\\.\pipe\winiotestpipe` var ok = []byte("ok") var bufSize = 65537 func main() { l, err := winio.ListenPipe(pipename, nil) if err != nil { return } defer l.Close() for { func() { conn, err := l.Accept() if err != nil { log.Fatal(err) } defer conn.Close() buf := make([]byte, bufSize) for { for { n, err := conn.Read(buf) if err != nil { return } if buf[n-1] == '\n' { break } } conn.Write(ok) } }() } }
クライアントサイド(C#)
注意するところは以下の通り
* 名前付きパイプのパスをGo言語側と同じにする必要があるので、\\.\pipe\
部分を削除しておく。
* UTF8でエンコードしてあげることで、GO側でも扱いやすくする。おそらくRead()したバッファは逆にUTF8からUTF16にエンコードする必要があるのではないかと思っているが、コード簡略化のため実施していない。
using System; using System.IO.Pipes; using System.Text; namespace ConsoleApp1 { class Program { static void PrintBuffer(byte[] buffer) { for (int i = 0; i < buffer.Length; i++) { Console.Write(Convert.ToChar(buffer[i])); } } static void PrintlnBuffer(byte[] buffer) { PrintBuffer(buffer); Console.WriteLine(); } static void Main(string[] args) { var client = new NamedPipeClientStream("winiotestpipe"); client.Connect(); var enc = new UTF8Encoding(); byte[] buffer = enc.GetBytes("a\n"); int len = buffer.Length; PrintBuffer(buffer); client.Write(buffer, 0, len); client.Flush(); byte[] rxbuf = new byte[2]; client.Read(rxbuf, 0, 2); PrintlnBuffer(rxbuf); Console.ReadLine(); } } }
まとめ
json
とかでやり取りしたらRPC通信的なことができてGoをバックエンドとしたデスクトップアプリとか書けるのかなぁ?と思っている。