/// <summary> /// 开启一个队列。 /// </summary> /// <param name="channelName"></param> /// <returns></returns> private IModel StartQueue(string channelName) { var connection = GetConnection(); if (connection == null) { return(null); } var channel = connection.CreateModel(); var queueName = channelName; if (string.IsNullOrEmpty(Setting.ExchangeType)) { channel.BasicQos(0, 1, false); channel.QueueDeclare(channelName, true, false, false, null); } else { var exchangeName = GetExchangeName(channelName); channel.ExchangeDeclare(exchangeName, Setting.ExchangeType); queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queueName, exchangeName, channelName); } var consumer = new CustomEventingBasicConsumer(channel, channelName); consumer.Received += (sender, args) => ConsumeData(sender as CustomEventingBasicConsumer, args); //消费消息 channel.BasicConsume(queueName, false, consumer); return(channel); }
private void RetryPublishData(CustomEventingBasicConsumer consumer, BasicDeliverEventArgs args, StoredSubject subject, Exception exception) { try { if (!consumer.Model.IsOpen) { return; } consumer.Model.BasicNack(args.DeliveryTag, false, false); if (subject != null && Setting.RetryTimes > 0 && subject.AcceptRetries < Setting.RetryTimes) { if (_notification != null) { var context = new SubscribeNotificationContext(subject.Name, subject.Body, exception); _notification.OnConsumeError(context); if (!context.CanRetry) { return; } } Task.Run(() => { Thread.Sleep((int)Setting.RetryDelayTime.TotalMilliseconds); try { subject.AcceptRetries++; PublishSubject(subject); } catch (Exception exp) { PersistSubject(subject, exp); } }); } } catch { } }
private void ConsumeData(CustomEventingBasicConsumer consumer, BasicDeliverEventArgs args) { if (!_subscribers.TryGetValue(consumer.ChannelName, out RabbitChannelCollection channels)) { return; } var found = channels.Find(consumer.Model); if (found == null || !consumer.Model.IsOpen) { return; } StoredSubject subject = null; try { object body; try { subject = Deserialize(typeof(StoredSubject), args.Body) as StoredSubject; if (subject == null) { return; } if (found.Handler.DataType == typeof(byte[])) { body = subject.Body; } else { body = Deserialize(found.Handler.DataType, subject.Body); } } catch (SerializationException) { if (found.Handler.DataType == typeof(byte[])) { body = args.Body; } else { body = Deserialize(found.Handler.DataType, args.Body); } } if (body != null) { found.Handler.Invoke(body); consumer.Model.BasicAck(args.DeliveryTag, false); } } catch (Exception exp) { Tracer.Error($"Throw exception when consume message of '{consumer.ChannelName}':\n{exp.Output()}"); RetryPublishData(consumer, args, subject, exp); } }