簡體   English   中英

如何使SimpleRpcClient.Call()成為阻塞調用,以實現與RabbitMQ的同步通信?

[英]How to get SimpleRpcClient.Call() to be a blocking call to achieve synchronous communication with RabbitMQ?

在RabbitMQ的.NET版本(2.4.1)中, RabbitMQ.Client.MessagePatterns.SimpleRpcClient具有帶有以下簽名的Call()方法:

    public virtual object[] Call(params object[] args);
    public virtual byte[] Call(byte[] body);
    public virtual byte[] Call(IBasicProperties requestProperties, byte[] body, out IBasicProperties replyProperties);

問題:

經過各種嘗試,該方法仍繼續不阻塞我期望的位置,因此無法處理響應。

問題:

我是否在SimpleRpcClient的安裝過程中缺少一些明顯的東西 ,或更早的IModelIConnection甚至是PublicationAddress

更多信息:

我也嘗試過QueueDeclare()方法的各種參數配置,但是沒有運氣。

string QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments);

這些設置的更多參考代碼:

IConnection conn = new ConnectionFactory{Address = "127.0.0.1"}.CreateConnection());
using (IModel ch = conn.CreateModel())
{
     var client = new SimpleRpcClient(ch, queueName);
     var queueName = ch.QueueDeclare("t.qid", true, true, true, null);

     ch.QueueBind(queueName, "exch", "", null);

     //HERE: does not block?
     var replyMessageBytes = client.Call(prop, msgToSend, out replyProp);
}

尋找其他地方:

還是我的“服務器端”代碼中可能存在問題? 無論是否使用BasicAck(),客戶端似乎都已繼續執行。

-縮短答案-

有點“ 您做錯了 ” ...

檢查IBasicProperties ,您應該將SimpleRpcServerHandleSimpleCall()一起使用

如果您偶然發現此問題,則可能是采取了與我一樣的錯誤方法,並且可能犯了類似的錯誤操作IBasicProperties的錯誤,從而損害了SimpleRpcServer正常運行的能力。

-長答案-

.NET的工作示例:在此處的BitBucket上找到我的工作示例:

https://bitbucket.org/NickJosevski/synchronous-rabbitmq-sample-.net

或者這是一個快速示例...

客戶端:

IConnection conn = new ConnectionFactory{Address = "127.0.0.1"}.CreateConnection();
using (IModel ch = conn.CreateModel())
{
    ch.ExchangeDeclare(Helper.ExchangeName, "direct");

    var queueName = ch.EnsureQueue();

    var client = new SimpleRpcClient(ch, queueName);

    var msgToSend = new Message(/*data*/).Serialize();

    IBasicProperties replyProp;

    var reply = client.Call(new BasicProperties(), msgToSend, out replyProp);
}

服務器端:

IConnection conn = new ConnectionFactory{Address = "127.0.0.1"}.CreateConnection();
using (IModel ch = conn.CreateModel())
{
    ch.ExchangeDeclare(Helper.ExchangeName, "direct");
    var queuename = ch.EnsureQueue();

    var subscription = new Subscription(ch, queuename);

    new MySimpleRpcServerSubclass(subscription).MainLoop();
}

internal class MySimpleRpcServerSubclass : SimpleRpcServer
{
    public MySimpleRpcServerSubclass(Subscription subscription) 
        : base(subscription) { }

    public override byte[] HandleSimpleCall(
        bool isRedelivered, IBasicProperties requestProperties, 
        byte[] body, out IBasicProperties replyProperties)
    {
        replyProperties = requestProperties;
        replyProperties.MessageId = Guid.NewGuid().ToString();

        var m = Message.Deserialize(body);
        var r = 
            new Response
            {
                Message = String.Format("Got {0} with {1}", m.Name, m.Body)
            };

        return r.Serialize();
    }
}

共享:

//helper:
public static string EnsureQueue(this IModel ch)
{
    var queueName = ch.QueueDeclare(QueueId, false, false, false, null);

    ch.QueueBind(queueName, ExchangeName, "", null);

    return queueName;
}

//NOTE: 
not all extension methods are explained here, such as *.Serialize()* 
as they're not relevant and just make for a cleaner example.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM