[英]Rabbitmq retrieve multiple messages using single synchronous call using .NET
[英]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的安裝過程中缺少一些明顯的東西 ,或更早的IModel , IConnection甚至是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 ,您應該將SimpleRpcServer與HandleSimpleCall()一起使用
如果您偶然發現此問題,則可能是采取了與我一樣的錯誤方法,並且可能犯了類似的錯誤操作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.