2013-05-08 171 views
14

私はお互いに通信する必要のあるWindowsサービスとGUIを持っています。いずれの場合も、いつでもメッセージを送信できます。Windows Named Pipes(.Net)との非同期双方向通信

NamedPipesの使用を検討していますが、同時に&をストリームに書き込むことはできないようです(少なくともこのケースをカバーするサンプルは見つかりません)。

この種の双方向通信は、単一のNamedPipe経由で行うことはできますか? または、2つのパイプを開く必要がありますか(GUI->サービスから1つ、サービス - > GUIから1つ)。

+2

あなたは、私は私のサービス/アプリケーションの通信、help.httpもここに良い例があるため、この方法を使用するWCF両面NamedPipesのを使用することができます。//tech.pro/tutorial/855/wcf-tutorial-基本的なプロセス間通信 –

答えて

25

この例では、WCFは、クライアント・アプリケーションを作成します

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)] 
public class SimpleService : ISimpleService 
{ 
    public string ProcessData() 
    { 
     // Get a handle to the call back channel 
     var callback = OperationContext.Current.GetCallbackChannel<IMyCallbackService>(); 

     callback.NotifyClient(); 
     return DateTime.Now.ToString(); 
    } 
} 

ホストサービス

class Server 
{ 
    static void Main(string[] args) 
    { 
     // Create a service host with an named pipe endpoint 
     using (var host = new ServiceHost(typeof(SimpleService), new Uri("net.pipe://localhost"))) 
     { 
      host.AddServiceEndpoint(typeof(ISimpleService), new NetNamedPipeBinding(), "SimpleService"); 
      host.Open(); 

      Console.WriteLine("Simple Service Running..."); 
      Console.ReadLine(); 

      host.Close(); 
     } 
    } 
} 

をサービスを実装

// Create a contract that can be used as a callback 
public interface IMyCallbackService 
{ 
    [OperationContract(IsOneWay = true)] 
    void NotifyClient(); 
} 

// Define your service contract and specify the callback contract 
[ServiceContract(CallbackContract = typeof(IMyCallbackService))] 
public interface ISimpleService 
{ 
    [OperationContract] 
    string ProcessData(); 
} 

を二重名前付きパイプを使用することができ、クライアントクラスを使用しますコールバック契約を実装しています。

class Client : IMyCallbackService 
{ 
    static void Main(string[] args) 
    { 
     new Client().Run(); 
    } 

    public void Run() 
    { 
     // Consume the service 
     var factory = new DuplexChannelFactory<ISimpleService>(new InstanceContext(this), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/SimpleService")); 
     var proxy = factory.CreateChannel(); 

     Console.WriteLine(proxy.ProcessData()); 
    } 

    public void NotifyClient() 
    { 
     Console.WriteLine("Notification from Server"); 
    } 
} 
+0

詳細な応答をありがとう。私は2つの名前付きパイプを使用するよりも簡単なので、このメソッドを使用しました。 –

+0

私はこの非常に詳細で便利なも知った:http://idunno.org/archive/2008/05/29/wcf-callbacks-a-beginners-guide.aspx –

+0

私はWindowsサービスを正常に実行することができますが、サービス参照を追加しようとしているときにサービスを見つける 'net.pipe:// localhost/service1'を取得します。 パイプからの読み取り中にエラーが発生しました:パイプが終了しました。 (109、0x6d)。 –

1

名前付きパイプストリームクラス(サーバーまたはクライアント)は、InOutのPipeDirectionで構築する必要があります。あなたのサービスでおそらく1つのNamedPipeServerStreamが必要です。これは任意の数のNamedPipeClientStreamオブジェクトで共有できます。 NamedPipeServerStreamをパイプと方向の名前で、NamedPipeClientStreamをパイプの名前、サーバーの名前、PipeDirectionで構成してください。

2

単一のポイントを使用してメッセージを蓄積すると(この場合は単一のパイプ)、パイプのシステム全体のロックを使用する必要があるだけでなく、メッセージの方向も自分で処理しなければなりません。

反対方向の2本のパイプを使用してください。

(2つのMSMQキューを使用する別のオプションもあります)。

関連する問題