private IModel GetReceiverChannel(ExchangeParam exchangeParam, QueueParam queueParam, ushort prefetchCount) { return(_subscriberChannelDic.GetOrAdd(queueParam.Queue, key => { var channel = _conn.CreateModel(); queueParam.Queue = queueParam.Queue ?? "UndefinedQueueName"; channel.QueueDeclare(queue: queueParam.Queue, durable: queueParam.Durable, exclusive: queueParam.Exclusive, autoDelete: queueParam.AutoDelete, arguments: queueParam.Arguments); if (exchangeParam != null) { exchangeParam.Exchange = exchangeParam.Exchange ?? "UndefinedExchangeName"; channel.ExchangeDeclare(exchange: exchangeParam.Exchange, type: exchangeParam.Type.ToString().ToLower(), durable: exchangeParam.Durable, autoDelete: exchangeParam.AutoDelete, arguments: exchangeParam.Arguments); channel.QueueBind(queue: queueParam.Queue, exchange: exchangeParam.Exchange, routingKey: queueParam.Queue); } channel.BasicQos(0, prefetchCount, false); return channel; })); }
public void SubscribeMessage <T>(string exchange, string queue, Action <T> handle, ushort prefetchCount = 10) { var exchangeParam = new ExchangeParam { Exchange = exchange, Durable = false }; var queueParam = new QueueParam { Queue = queue, Durable = false }; var channel = GetReceiverChannel(exchangeParam, queueParam, prefetchCount); ConsumeEvent(channel, handle, queueParam.Queue); }
public void SubscribeEvent <T>(string exchange, string queue, Func <Action <T> > resolve, ushort prefetchCount = 10) { var exchangeParam = new ExchangeParam { Exchange = exchange }; var queueParam = new QueueParam { Queue = queue }; var channel = GetReceiverChannel(exchangeParam, queueParam, prefetchCount); ConsumeEvent(channel, resolve, queueParam.Queue); }
private void ConsumeEvent <T>(IModel channel, Func <Action <T> > resolve, string queue) { var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { Task.Run(() => { try { var msg = _serializer.Deserialize <T>(ea.Body); resolve.Invoke()(msg); } catch (Exception ex) { var innermostEx = ex.GetInnestException(); var dlxName = GetDeadLetterName(queue); var dlxExchangeParam = new ExchangeParam { Exchange = dlxName }; var dlxQueueParam = new QueueParam { Queue = dlxName }; using (var deadLetterMsgChannel = CreatePublisherChannel(dlxExchangeParam, dlxQueueParam)) { var properties = deadLetterMsgChannel.CreateBasicProperties(); properties.Persistent = true; var routingKey = dlxExchangeParam.Exchange; var dlx = new DeadLetterMsg { QueueName = queue, ExMsg = innermostEx.Message, ExStack = innermostEx.StackTrace, ThrowTime = DateTimeOffset.Now, BodyString = _serializer.BytesToString(ea.Body) }; deadLetterMsgChannel.BasicPublish(dlxExchangeParam.Exchange, routingKey, properties, _serializer.Serialize(dlx)); } } finally { channel.BasicAck(ea.DeliveryTag, false); } }); }; channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer); }
public void ReceiveMessage <T>(Func <Action <T> > resolve, ushort prefetchCount = 10) { var messageName = GetTypeName(typeof(T)); var exchangeParam = new ExchangeParam { Exchange = messageName, Durable = false }; var queueParam = new QueueParam { Queue = messageName, Durable = false }; var channel = GetReceiverChannel(exchangeParam, queueParam, prefetchCount); ConsumeMessage(channel, resolve, messageName); }
public void ReceiveEvent <T>(Func <Action <T> > resolve, ushort prefetchCount = 10) { var eventName = GetTypeName(typeof(T)); var exchangeParam = new ExchangeParam { Exchange = eventName }; var queueParam = new QueueParam { Queue = eventName }; var channel = GetReceiverChannel(exchangeParam, queueParam, prefetchCount); ConsumeEvent(channel, resolve, eventName); }
public void ListenMessage <T>(Action <T> handle, ushort prefetchCount = 10) { var exchangeName = GetTypeName(typeof(T)); var methodFullName = $"{handle.Method.ReflectedType?.FullName}.{handle.Method.Name}[{exchangeName}][{Guid.NewGuid()}]"; var exchangeParam = new ExchangeParam { Exchange = exchangeName, Durable = false }; var queueParam = new QueueParam { Queue = methodFullName, Durable = false, Exclusive = true, AutoDelete = true }; var channel = GetReceiverChannel(exchangeParam, queueParam, prefetchCount); ConsumeMessage(channel, handle, queueParam.Queue); }
public void RepublishDeadLetterEvent <T>(string deadLetterQueueName, ushort prefetchCount = 1) { var queueParam = new QueueParam { Queue = deadLetterQueueName }; var channel = GetReceiverChannel(null, queueParam, prefetchCount); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var msg = _serializer.Deserialize <DeadLetterMsg>(body); var republishExchangeParam = new ExchangeParam { Exchange = $"republish-{deadLetterQueueName}", Durable = true }; var republishQueueParam = new QueueParam { Queue = FromDeadLetterName(deadLetterQueueName), Durable = true }; using (var republishChannel = CreatePublisherChannel(republishExchangeParam, republishQueueParam)) { var properties = republishChannel.CreateBasicProperties(); properties.Persistent = true; var routingKey = republishExchangeParam.Exchange; var deadLetter = _serializer.FromString <T>(msg.BodyString); republishChannel.BasicPublish(republishExchangeParam.Exchange, routingKey, properties, _serializer.Serialize(deadLetter)); } channel.BasicAck(ea.DeliveryTag, false); }; channel.BasicConsume(queue: deadLetterQueueName, autoAck: false, consumer: consumer); }
private IModel CreatePublisherChannel(ExchangeParam exchangeParam, QueueParam queueParam) { var channel = _conn.CreateModel(); exchangeParam.Exchange = exchangeParam.Exchange ?? "UndefinedExchangeName"; channel.ExchangeDeclare(exchange: exchangeParam.Exchange, type: exchangeParam.Type.ToString().ToLower(), durable: exchangeParam.Durable, autoDelete: exchangeParam.AutoDelete, arguments: exchangeParam.Arguments); if (queueParam == null) { return(channel); } queueParam.Queue = queueParam.Queue ?? "UndefinedQueueName"; channel.QueueDeclare(queue: queueParam.Queue, durable: queueParam.Durable, exclusive: queueParam.Exclusive, autoDelete: queueParam.AutoDelete, arguments: queueParam.Arguments); channel.QueueBind(queue: queueParam.Queue, exchange: exchangeParam.Exchange, routingKey: queueParam.Queue); return(channel); }