RPC rabbitMQ sends only one message and receive one client

Viewed 12

I used the tutorial from rabbitMQ on RCP in C#

server program.cs

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
namespace RabbitMQServerTest
{
internal class Program
{
    static void Main(string[] args)
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };
        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue:"RPC_TEST",true,false,false,null);
                channel.BasicQos(0,1,false);
                var consumer = new EventingBasicConsumer(channel);
                channel.BasicConsume(queue: "RPC_TEST",
                            autoAck: true, consumer: consumer);
                Console.WriteLine(" [x] Awaiting RPC requests");
                consumer.Received += (model, ea) =>
                {
                    string response = null;

                    var body = ea.Body.ToArray();
                    var props = ea.BasicProperties;
                    var replyProps = channel.CreateBasicProperties();
                    replyProps.CorrelationId = props.CorrelationId;

                    try
                    {
                        var message = Encoding.UTF8.GetString(body);
                        int n = int.Parse(message);
                        Console.WriteLine($" [.] fib({message}) from  {replyProps.CorrelationId }");
                        response = fib(n).ToString();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(" [.] " + e.Message);
                        response = "";
                    }
                    finally
                    {
                        var responseBytes = Encoding.UTF8.GetBytes(response);
                        channel.BasicPublish(exchange: "", routingKey: props.ReplyTo,
                          basicProperties: replyProps, body: responseBytes);
                        channel.BasicAck(deliveryTag: ea.DeliveryTag,
                          multiple: false);
                    }
                };

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }

    private static int fib(int n)
    {
        if (n == 0 || n == 1)
        {
            return n;
        }

        return fib(n - 1) + fib(n - 2);
    }
}
}

client program.cs

internal class Program
{
    private static RpcClient m_rpcClient;

    static void Main(string[] args)
    {
        m_rpcClient = new RpcClient();

        callFib();

        m_rpcClient.Close();


    }

    static void callFib()
    {
        Console.WriteLine("Write number:");
        var num = Console.ReadLine();
        if (num != "q")
        {
            var response = m_rpcClient.Call("30").Result;
            Console.WriteLine(" [.] Got '{0}'", response);
            callFib();
        }
    }
}

client RpcClient.cs

public class RpcClient :IDisposable
{
    private readonly IConnection connection;
    private readonly IModel channel;
    private readonly string replyQueueName;
    private readonly EventingBasicConsumer consumer;
     private ConcurrentDictionary<string, TaskCompletionSource<string>> m_ActiveQueue = new ConcurrentDictionary<string, TaskCompletionSource<string>>();
    private readonly IBasicProperties props;

    public RpcClient()
    {
        var factory = new ConnectionFactory() { HostName = "localhost" };

        connection = factory.CreateConnection();
        channel = connection.CreateModel();
        replyQueueName = channel.QueueDeclare().QueueName;
        consumer = new EventingBasicConsumer(channel);

       

        consumer.Received += (model, ea) =>
        {
            var body = ea.Body.ToArray();
            var response = Encoding.UTF8.GetString(body);
            if (m_ActiveQueue.TryRemove(ea.BasicProperties.CorrelationId, out
            var taskCompletionSource))
            {
                taskCompletionSource.SetResult(response);
            }
        };

        channel.BasicConsume(
            consumer: consumer,
            queue: replyQueueName,
            autoAck: true);
    }

    public Task<string> Call(string message)
    {
        var props = channel.CreateBasicProperties();
        var correlationId = Guid.NewGuid().ToString();
        props.CorrelationId = correlationId;
        props.ReplyTo = replyQueueName;
        var taskCompletionSource = new TaskCompletionSource<string>();
        var messageBytes = Encoding.UTF8.GetBytes(message);
        channel.BasicPublish(
            exchange: "",
            routingKey: "RPC_TEST",
            basicProperties: props,
            body: messageBytes);
        m_ActiveQueue.TryAdd(correlationId, taskCompletionSource);
        return taskCompletionSource.Task;
    }

    public void Close()
    {
        try
        {
            channel?.Close();
            connection?.Close();
        }
        catch (Exception ex)
        {

        }
       
    }

    public void Dispose()
    {
        Close();
    }
}

It's working only with single message from single client if I'm trying to run few clients , only the first that sent the message get response the seconds message sends the server doesn't even get to the consumer.Received event in server program.cs

0 Answers
Related