在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(),客户端都会继续执行。
答案 0 :(得分:3)
- 简短回答 -
“你做错了”......
检查 IBasicProperties ,您应该将 SimpleRpcServer 与 HandleSimpleCall()
一起使用
如果你偶然发现了这个问题,你或者采取了错误的方法,并且可能会犯一个类似的错误,即错误地操纵 IBasicProperties ,从而损害 SimpleRpcServer <的能力/ em>正常运行。
- LONG ANSWER -
.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.