简体   繁体   中英

How to try-catch a RPC call to an offline RPC server?

I'm searching for hours how to proceed if we make a RPC call to a server who is online but who don't run the RPC server.

The only thing i'm doing in my code is to ping our failover IP address to check if the server is runnning, but if i make a RPC call with my C# application, it's crash.

The RPC Call function :

public string Call(string message)
{
    var corrId = Guid.NewGuid().ToString();
    var props = channel.CreateBasicProperties();
    props.ReplyTo = replyQueueName;
    props.CorrelationId = corrId;

    var messageBytes = Encoding.UTF8.GetBytes(message);
    channel.BasicPublish(exchange: "", routingKey: "rpc_queue", basicProperties: props, body: messageBytes);

    while(true)
    {
        var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
        if(ea.BasicProperties.CorrelationId == corrId)
        {
            return Encoding.UTF8.GetString(ea.Body);
        }
    }
}

Does anyone have a solution ?

PS : RabbitMQ confesses to don't solve these following problems :

Our code is still pretty simplistic and doesn't try to solve more complex (but important) problems, like:

How should the client react if there are no servers running?

Should a client have some kind of timeout for the RPC?

Thanks.

For those who have this problem, I solved this like :

try
{
    var task = Task.Run(() => rpcClient.Call(data_encoded));
    if (task.Wait(TimeSpan.FromSeconds(3)))
    {
        response = task.Result;
    }
    else
    {
        throw new Exception("Timed out");
    }
    Console.WriteLine("RESPONSE : " + response);
}
catch (Exception e)
{
    // Some code here ...
}

I am new to RabbitMQ and RPC, but am using the following check to see if the server is alive before making an RPC call from my client:

private bool IsRpcServerAlive()
{
   // create a temporary channel since it will not be
   // reusable if an exception is thrown
   using (var tempChannel = connection.CreateModel())
   {
      try
      {
         // throws an exception if the Queue does not exist
         var declareResult = channel.QueueDeclarePassive("rpc_queue");
         // RPC server is the only consumer of the Queue
         return declareResult.ConsumerCount > 0;
      }
      catch (RabbitMQ.Client.Exceptions.OperationInterruptedException)
      {
         return false;
      }
   }
}

This works for me as my server is the only consumer of the Queue. For more information on passive declaration see https://www.rabbitmq.com/dotnet-api-guide.html#passive-declaration

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