WCFで名前付きパイプを使ったプロセス間通信 - IronPython でサーバーとクライアントを実行
WCFで名前付きパイプを使ったプロセス間通信を実施してみる。
サービスは C# で、サーバー・クライアントは IronPython でコーディングしてみた。
使用した環境は以下の通り。
- .NET Framework 3.5
- IronPython 2.6
サービスの作成
まず、C# でサービスをコーディングする。サービスの定義には以下のような属性を使用する。
- ServiceContract でサービスを定義
- OperationContract でサービスで公開するメソッドを定義
- ServiceBehavior でサービスの振る舞いを定義(サンプルではシングルトンを指定)
- DataContract でサービスでやり取りするデータを定義
- DataMember でデータのメンバーを定義
SampleService.cs
using System; using System.Runtime.Serialization; using System.ServiceModel; namespace SampleLib { //サービスインターフェース [ServiceContract] public interface ISampleService { [OperationContract] void AddData(SampleData data); } //サービスクラス [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class SampleService : ISampleService { //メソッドの実装 public void AddData(SampleData data) { Console.WriteLine("data: id={0}, name={1}", data.Id, data.Name); } } //データクラス [DataContract] public class SampleData { [DataMember] public int Id; [DataMember] public string Name; } }
ビルド
SampleService.cs をビルドしてアセンブリファイル(.dll)を作成。
>csc /target:library /out:SampleLib.dll SampleService.cs
サーバーの作成
サービスの公開に ServiceHost クラスを使用する。
今回は名前付きパイプを使うため、以下を使ってエンドポイントの設定を行う。
なお、シングルトンでサービスを公開するには ServiceHost のコンストラクタにサービスクラスのインスタンスを渡せばよい。(ただし、ServiceBehavior 属性で InstanceContextMode に Single を設定しておく必要あり)
sample_server.py
# coding: utf-8 import clr clr.AddReference("System.ServiceModel") clr.AddReference("SampleLib.dll") from System import * from System.ServiceModel import * from SampleLib import * #サービスをインスタンス化 service = SampleService() #自己ホスト用のクラスをインスタンス化 host = ServiceHost(service) #名前付きパイプのバインディングをインスタンス化 binding = NetNamedPipeBinding() #ISampleService に対するエンドポイントを設定 host.AddServiceEndpoint(ISampleService, binding, "net.pipe://localhost/sample") host.Open() Console.WriteLine("press enter key to terminate service") Console.ReadLine() host.Close()
クライアントの作成
クライアントでは、サーバーで設定したエンドポイントと同じ設定を使って、ジェネリックな ChannelFactory をインスタンス化、CreateChannel でサービスのプロキシを取得してサービスの呼び出しを行う。
sample_client.py
# coding: utf-8 import clr clr.AddReference("System.ServiceModel") clr.AddReference("SampleLib.dll") from System.ServiceModel import * from SampleLib import * binding = NetNamedPipeBinding() factory = ChannelFactory[ISampleService](binding, "net.pipe://localhost/sample") #サービスプロキシの取得 service = factory.CreateChannel() data = SampleData() data.Id = 100 data.Name = "テストデータ" #サービスの実行 service.AddData(data) factory.Close()
実行
サーバー実行
>ipy sample_server.py press enter key to terminate service
クライアント実行
>ipy sample_client.py
サーバーの実行結果
>ipy sample_server.py ・・・ data: id=100, name=テストデータ