public void Listen()
{
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = _exchange.Hostname;
factory.VirtualHost = _exchange.VirtualHost;
factory.Port = AmqpTcpEndpoint.UseDefaultPort;
_connection = factory.CreateConnection();
_channel = _connection.CreateModel();
// declare the exchange
_channel.ExchangeDeclare(_exchange.Name, ExchangeType.Topic, true);
// declare the queue
_queue = _channel.QueueDeclare(_queueName, false, true, false, null);
// create a basic queueing consumer
QueueingBasicConsumer consumer = new QueueingBasicConsumer(_channel);
String consumerTag = _channel.BasicConsume(_queue.QueueName, false, consumer);
// let anyone interested know that we've started
this.MarkAsStarted();
// and consume until we've been disposed
while (!_isDisposing)
{
while (_bindings.Count > 0)
{
try
{
BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
IBasicProperties props = e.BasicProperties;
// create an amqp envelope out of the byte array
AmqpEnvelope env = new AmqpEnvelope(e.Body);
// do some receipt-specific stuff
this.LogAndSetReceiptHeaders(env, props);
// raise the envelope to interested clients
this.Raise_EnvelopeReceived_Event(env);
// wait for the envelope to be marked as processed before getting the next message
env.WaitToBeProcessed();
// we may want the WaitToBeProcessed method to return a completion type
// one day so that we can do smarter things than just "ack", for example,
// "nack'ing" events we failed to process.
_channel.BasicAck(e.DeliveryTag, false);
}
catch (EndOfStreamException)
{
// this happens when we get disconnected somehow. Typically, this
// happens when the process is shutting down. Let's log this and
// not freak out about it.
LOG.InfoFormat("Rabbit Queue {0} is no longer listening for new events", _queueName);
break;
}
catch (Exception ex)
{
// The consumer was removed, either through
// channel or connection closure, or through the
// action of IModel.BasicCancel().
LOG.Error(string.Format(
"The Rabbit queue {0} encountered an exception attempting to consume a message.", _queueName
), ex);
break;
}
}
if (_bindings.Count == 0)
{
// avoid a hard-loop
Thread.Sleep(100);
}
}
}