.NETリモーティングでIPCチャネルを使用する
.NET2.0から.NETリモーティングで使用できるチャネルに新しくIPCチャネルが追加された。
これは同じマシン間での通信、純粋なプロセス間通信用のチャネルで内部実装には名前付きパイプが使われている。(メモリマップドファイルやったかな?どっちかは忘れた)で、ちょうど同じマシン間でプロセス間通信をする必要があったので使ってみることにした。
まずアプリケーション構成ファイルにチャネルを定義する。
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.runtime.remoting> <application> <channels> <channel ref="ipc"> </channel> </channels> </application> <customErrors mode="Off" /> </system.runtime.remoting> </configuration>
で、これを公開する。
Program.cs
static void Main() { RemotingConfiguration.Configure("Remoting.config", false); HogeService hogeService = new HogeService(); // SAOで公開 RemotingServices.Marshal(hogeService, "hogeService.rem"); }
このサービスにアクセスするコード
Client.cs
static void Main() { HogeService hogeService = (HogeService)Activator.GetObject("ipc://localhost/hogeService.rem"); hogeService.Do(); }
System.Runtime.Remoting.RemotingException: IPC ポートに接続できません。指定されたファイルが見つかりません。
「指定されたファイルが見つかりません」?なんのこっちゃ?としばらく考えてみて気づいたが、IPCチャネルは名前付きパイプを使っている。なら、そのパイプ名はどこで指定するんや?という話。
MSDNをよく見てみるとアプリケーション構成ファイルでIPCチャネルを指定する場合の必須属性があった。
App.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.runtime.remoting> <application> <channels> <channel ref="ipc" portName="hogehoge"> </channel> </channels> </application> <customErrors mode="Off" /> </system.runtime.remoting> </configuration>
「portName」属性でパイプ名を指定できるようになっている。
クライアント側のコードを書き直す。
Client.cs
static void Main() { HogeService hogeService = (HogeService)Activator.GetObject("ipc://hogehoge/hogeService.rem"); hogeService.Do(); }
これで正常に動いた。