简体   繁体   中英

rabbitmq consumer becomes a producer

I am receiving messages from RabbitMQ inside a consumer. I have to process that message and publish the processed message into a different queue. How would I accomplish this?

My code is

using (IConnection connection = factory.CreateConnection())
{
    using (IModel channel = connection.CreateModel())
    {
        if (!String.IsNullOrEmpty(EXCHANGE_NAME))
            channel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Direct, durable);

        if (!String.IsNullOrEmpty(QUEUE_NAME))
            channel.QueueDeclare(QUEUE_NAME, false, false, false, null);

        string data = "";
        EventingBasicConsumer consumer = new EventingBasicConsumer();
        consumer.Received += (o, e) =>
        {
            //This is the received message
            data = data + Encoding.ASCII.GetString(e.Body) + Environment.NewLine;
            string processed_data = "processed data = " + data; 
            //I want to write some code here to post the processed message to a different queue.
            //or other idea is "can I use duplex services? 

        };
        string consumerTag = channel.BasicConsume(QUEUE_NAME, true, consumer);

        channel.QueueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY, null);
        channel.QueueUnbind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY, null);
    }
}

The bottom line is that you can share the connection between threads, but not the channel. So in your example you can use the same connection, but you'll need to create a new channel when you want to publish (because the consumer.Received event will be raised on a different thread):

using (IConnection connection = factory.CreateConnection())
{
    using (IModel channel = connection.CreateModel())
    {
        if (!String.IsNullOrEmpty(EXCHANGE_NAME))
            channel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Direct, durable);

        if (!String.IsNullOrEmpty(QUEUE_NAME))
            channel.QueueDeclare(QUEUE_NAME, false, false, false, null);

        string data = "";
        EventingBasicConsumer consumer = new EventingBasicConsumer();
        consumer.Received += (o, e) =>
        {
            //This is the received message
            data = data + Encoding.ASCII.GetString(e.Body) + Environment.NewLine;
            string processed_data = "processed data = " + data; 
            //I want to write some code here to post the processed message to a different queue.
            //or other idea is "can I use duplex services? 

            using (IModel channel = connection.CreateModel())
            {
                channel.Publish( ... );
            }

        };
        string consumerTag = channel.BasicConsume(QUEUE_NAME, true, consumer);

        channel.QueueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY, null);
        channel.QueueUnbind(QUEUE_NAME, EXCHANGE_NAME, ROUTING_KEY, null);

        // don't dispose of your channel until you've finished consuming
    }

    // don't dispose of your connection until you've finished consuming
}

Make sure you don't dispose of your consumer channel until you want to stop consuming. The same goes for the connection. It's a common mistake.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM