2017-09-06 6 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 단계에서 실패하면 실제 메시지 대신 null이 반환됩니다. 아무도 내가 여기에없는 것을 제안 할 수 있습니까?

미리 감사드립니다.

+0

'activeInstance'가 사용 된 두 줄 :'string activeInstance = null;'return activeInstance;'이 변수는 절대로 설정하지 마십시오. – Reniuz

+0

그것은 실수였습니다. 실제 코드에서는 null이 여전히 유효합니다. @Reniuz – Mahek

+0

실제 코드를 추가하십시오. 이제 메시지는 null이어야하지만 GetString()이 string을 반환하기 때문에 메시지를 반환 할 수 없습니다. – Reniuz

답변

2

을 제외한 모든 항목에 activeInstance을 절대로 설정하지 마십시오.

비동기 API를 사용하고있는 것으로 보입니다. 즉, RunRabbitMQ 메서드 호출이 완료된 후에 오랫동안 RabbitMQ에서 메시지를 검색하고 있습니다. 그렇지 않으면 모든 소비자를 즉시 ​​처리하지 않은 것입니다. 돌아 오는 기계.

메시지를 동 기적으로 검색하려는 경우 (이 경우 동기식 메서드 호출 내에서) 메시지를 사용할 수있을 때까지 기다려야합니다. 이를 위해 channel.BasicGet(...) 인 '풀 API'를 사용하고 싶습니다.

+0

그것은 실수였습니다. 실제 코드에서는 적절하고 여전히 null이되었습니다. @yaakov – Mahek

+1

당신은 여전히 ​​동시성 문제가 있습니다 - 이벤트에서 변수를 설정하고 있지만 이벤트가 발생하지 않습니다. 메서드가 끝납니다. – yaakov

+0

WCF 서비스에서 이벤트가 트리거되지 않음을 알았습니다. 콘솔 응용 프로그램에서 테스트 한 동일한 코드와 이벤트가 트리거되고 그 값을 반환 할 수있는 반면. WCF에서 트리거 할 수없는 이유는 무엇입니까? @yaakov – Mahek