我有一个RabbitMQ SimpleRpcServer,我想知道如何在完成后正确处理它。该模式有一个主循环,它阻塞直到它收到消息,处理消息,然后再次阻塞。这意味着为了打破循环,我必须发送一个特殊编码的消息,处理程序可以使用它来打破循环。
我已经读过RabbitMQ频道应该从创建它们的同一个线程中访问。如果这是真的(我找不到源代码),这是否意味着要配置我的SimpleRpcServer,我必须创建一个专门用于将关闭消息发送到主循环的新通道?
这是伪代码:
主循环(actual code here):
//I run this on a ThreadPool thread
foreach (var evt in m_subscription) //blocks until a message appears
{
ProcessRequest(evt);
}
处理程序:
private void ProcessRequest(evt)
{
if(evt.BasicProperties.ContentType == "close") //close flag
{
base.Close();
}
else
{
//process message
}
}
处置代码(专门用于取消主循环创建新通道):
//I call this from the main thread
public void Dipose()
{
var channel = new Channel();
var props = new Properties("close"); //close flag
channel.BasicPublish(queueName, props);
channel.Dispose();
}
请注意,我遗漏了一些初始化和处理代码。我知道这段代码不会编译。
答案 0 :(得分:1)
是的,你不应该在两个或多个线程之间共享通道,请阅读http://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v3.2.4/rabbitmq-dotnet-client-3.2.4-user-guide.pdf“2.10。不应在线程“
之间共享IModel要关闭频道,您可以使用频道创建订阅线程,然后关闭主线程上的频道,如下所示:
初始化连接,频道等......
ConnectionFactory connection_factory = new ConnectionFactory();
IConnection conn = null;
IModel channel = null;
Subscription sub = null;
private void Connect()
try
{
conn = connection_factory.CreateConnection();
channel = conn.CreateModel();
sub = new Subscription(channel, your_queue, true);
StartSubscribeThread (sub);
….
创建你的主题:
public void StartSubscribeThread(Subscription sub)
{
var t = new Thread(() => InternalStartSubscriber(sub));
t.Start();
}
private void InternalStartSubscriber(Subscription sub)
{
foreach (BasicDeliverEventArgs e in sub)
{
//Handle your messages
}
}
最后:
private void Disconnet()
sub.Close();
channel.Close();
channel.Dispose();
通过这种方式,您可以避免创建另一个关闭第一个
的频道