Mahek
Mahek

Reputation: 562

How to consume RabbitMQ in WCF?

I have a scenerio,where a executable is the producer and WCF service is the consumer.

WCF service WorkFlow is as follows:

1)Service invokes the executable (producer), this executable is another process which produces the messages into RabbitMQ Queue.

2)Service has to consume the messages from the RabbitMQ Queue

3)Returns the data to client.

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;
        }
    }
}

So far service is able to invoke executable and messages are produced in the queue.

But service fails from step 2, it is returning null instead of actual message. Can anybody suggest me what I am missing here?

Thanks in Advance.

Upvotes: 0

Views: 1612

Answers (1)

yaakov
yaakov

Reputation: 5850

You're never setting activeInstance to anything except null.

You appear to be using the asynchronous API, which means that you're retrieving the message from RabbitMQ long after the RunRabbitMQ method call has completed... or you would be if you didn't immediately dispose of all the consumer machinery when returning.

If you want to retrieve messages synchronously - in this case, within a synchronous method call - you'll need to wait for a message to become available. For this, you'd want to use the 'pull API', which is channel.BasicGet(...).

Upvotes: 2

Related Questions