2017-09-06 9 views
0

私は実行可能ファイルがプロデューサで、WCFサービスがコンシューマであるscenerioを持っています。次のようにWCFでRabbitMQを使用するには?

WCFサービスワークフローは、次のとおり

1)サービスが実行可能(プロデューサー)を呼び出して、この実行可能ファイルがRabbitMQのキューにメッセージを生成する別のプロセスです。

2)サービス)のRabbitMQキュー

3からのメッセージを消費しているクライアントにデータを返します。

using RabbitMQ.Client; 
using RabbitMQ.Client.Events; 
using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace ConnectionServices 
{ 

    public class Connection : IConnection 
    { 
     public string ConnectSite(string provider, string server, string siteName) 
     { 
      InvokeProducer(provider, server, siteName); 
      string activeInstance = RunRabbitMQ(); 
      return activeInstance; 

     } 
     public void InvokeProducer(string provider, string server, string siteName) 
     { 
      string siteManagerExePath = @"C:\Users\mbmercha\Documents\Visual Studio 2015\Projects\Producer\Producer\bin\Debug\Producer.exe"; 
      try 
      { 
       ProcessStartInfo startInfo = new ProcessStartInfo(); 
       Process siteManagerProcess = new Process(); 
       startInfo.FileName = siteManagerExePath; 
       startInfo.Arguments = string.Format("{0} {1} {2} {3}", "-b ", provider, server, siteName); 
       siteManagerProcess.StartInfo = startInfo; 
       siteManagerProcess.Start(); 
       siteManagerProcess.WaitForExit(); 

      } 
      catch (Exception e) 
      { 

      } 
     } 
     public string RunRabbitMQ() 
     { 
      var factory = new ConnectionFactory() { HostName = "localhost" }; 
      string activeInstance = null; 
      using (var connection = factory.CreateConnection()) 
      using (var channel = connection.CreateModel()) 
      { 
       channel.QueueDeclare("DurableQueue", true, false, false, null); 
       channel.ExchangeDeclare("DurableExchange", ExchangeType.Topic, true); 
       channel.QueueBind("DurableQueue", "DurableExchange", "durable"); 
       var consumer = new EventingBasicConsumer(channel); 

       consumer.Received += (model, ea) => 
       { 
        var body = ea.Body; 
        var message = Encoding.UTF8.GetString(body); 
        activeInstance = message; 
       }; 
       channel.BasicConsume(queue: "DurableQueue", 
            autoAck: false, 
            consumer: consumer); 


      } 
      return activeInstance; 
     } 
    } 
} 

これまでのところ、サービスは実行可能ファイルを呼び出すことができ、メッセージはキューで生成されます。

しかし、サービスは手順2から失敗します。実際のメッセージではなくヌルが返されます。 誰でも私がここで紛失しているものを教えてもらえますか?

ありがとうございました。

+0

'activeInstance'が使用されているこれら2行:' string activeInstance = null; 'return activeInstance;'この変数は設定しないでください。 – Reniuz

+0

実際のコードでは正しく入力されていますが、まだnullになっています@Reniuz – Mahek

+0

実際のコードを追加してください。メッセージはnullでなければなりませんが、GetString()がstringを返すため、メッセージを返すことはできません。 – Reniuz

答えて

2

null以外はactiveInstanceに決して設定しないでください。

非同期APIを使用しているように見えます。つまり、RunRabbitMQメソッド呼び出しが完了してから長い間、RabbitMQからメッセージを取得しています。または、すべてのコンシューマをすぐに処分しなかった場合返品時の機械。

メッセージを同期的に(この場合は同期メソッド呼び出し内で)取得する場合は、メッセージが利用可能になるまで待つ必要があります。そのためには、 'pull API'(channel.BasicGet(...))を使用します。

+0

実際のコードでは正しいですがまだnullです@yaakov – Mahek

+1

あなたはまだ同期性の問題があります - あなたはイベントから変数を設定していますが、イベントは以前は起動しませんメソッドは終了します。 – yaakov

+0

WCFサービスから、イベントがトリガされていないことがわかりました。コンソールアプリケーションでテストしたコードと同じコードでイベントがトリガされ、値を返すことができます。 WCFでトリガできないのはなぜですか? @yaakov – Mahek

関連する問題