Пример #1
0
        public ConsumerExecutionContext(
            Func <byte[], MessageProperties, MessageReceivedInfo, Task> onMessageHandler,
            MessageReceivedInfo info,
            MessageProperties properties,
            byte[] body,
            IBasicConsumer consumer)
        {
            Preconditions.CheckNotNull(onMessageHandler, "userHandler");
            Preconditions.CheckNotNull(info, "info");
            Preconditions.CheckNotNull(properties, "properties");
            Preconditions.CheckNotNull(body, "body");
            Preconditions.CheckNotNull(consumer, "consumer");

            OnMessageHandler = onMessageHandler;
            Info             = info;
            Properties       = properties;
            Body             = body;
            Consumer         = consumer;
        }
Пример #2
0
        /// <summary>
        /// 发布(执行),等同于 执行Onclick方法(执行委托所关联的方法)
        /// 生产者发布带有事务确认的操作
        /// 正确理解的理解方式是,通道(model)要执行的方法,相当于model.pubishAction()。此处分开写了,model一个参数,publishAction一个参数。
        /// </summary>
        /// <param name="model">通道对象</param>
        /// <param name="publishAction">要执行的方法,参数就是model通道。</param>
        /// <returns></returns>
        public override void Publish(IModel model, byte[] body, MessageProperties messageProperties, Action <IModel, byte[], MessageProperties> publishAction)
        {
            base.SetModel(model);

            ulong sequenceNumber = model.NextPublishSeqNo;

            Timer timer = null;

            timer = new Timer(state =>
            {
                //改为记录日志的方式处理超时结果。wangyunpeng。2017-8-24
                (state as Timer).Dispose();
                this._dictionary.Remove(sequenceNumber);
                ConsoleLogger.ErrorWrite("生产者发布消息超时。 序列号: {0}", sequenceNumber);
                EventBus.Instance.Publish(new ConfirmedMessageTimeOutEvent(body, messageProperties, new MessageConfirmedTimeOutInfo(sequenceNumber, string.Format("生产者确认超时后,{0}秒后等待来自序列号为{1}的ACK或NACK ", this._timeoutSeconds, sequenceNumber))));
            }, timer, this._timeoutSeconds * 1000, Timeout.Infinite);

            //在执行生产者发布消息之前,增加对这个消息的事务操作,包括事务成功和事务失败的处理。
            this._dictionary.Add(sequenceNumber, new ConfirmActions
            {
                OnAck = () =>
                {
                    timer.Dispose();
                    ConsoleLogger.InfoWrite("生产者发布的消息通过服务器的确认。序列号: {0}", sequenceNumber);
                    EventBus.Instance.Publish(new ConfirmedMessageEvent(body, messageProperties, new MessageConfirmedInfo(sequenceNumber, true)));
                },
                OnNack = () =>
                {
                    timer.Dispose();
                    ConsoleLogger.ErrorWrite("生产者发布的消息未通过服务器的确认。序列号: {0}", sequenceNumber);
                    EventBus.Instance.Publish(new ConfirmedMessageEvent(body, messageProperties, new MessageConfirmedInfo(sequenceNumber, false)));
                },
                Cancel            = () => timer.Dispose(),
                Body              = body,
                MessageProperties = messageProperties,
                PublishAction     = publishAction
            });

            publishAction(model, body, messageProperties);//真正执行生产者发布消息的操作。RabbitAdvancedBus.Publish.cs文件this._publisher.Publish(......)
        }
Пример #3
0
        /// <summary>
        /// 消费者处理交付。IBasicConsumer接口自动完成调用。
        /// </summary>
        /// <param name="consumerTag"></param>
        /// <param name="deliveryTag"></param>
        /// <param name="redelivered"></param>
        /// <param name="exchange"></param>
        /// <param name="routingKey"></param>
        /// <param name="properties"></param>
        /// <param name="body"></param>
        public void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, byte[] body)
        {
            ConsoleLogger.DebugWrite("HandleBasicDeliver on consumer: {0}, deliveryTag: {1}", consumerTag, deliveryTag);

            if (this._disposed)
            {
                // this message's consumer has stopped, so just return
                ConsoleLogger.InfoWrite("Consumer has stopped running. Consumer '{0}' on queue '{1}'. Ignoring message", this.ConsumerTag, queue.Name);
                return;
            }

            if (this._onMessage == null)
            {
                ConsoleLogger.ErrorWrite("User consumer callback, 'onMessage' has not been set for consumer '{0}'. Please call InternalConsumer.StartConsuming before passing the consumer to basic.consume", this.ConsumerTag);
                return;
            }

            var messageReceivedInfo = new MessageReceivedInfo(consumerTag, deliveryTag, redelivered, exchange, routingKey, queue.Name);
            var messsageProperties  = new MessageProperties(properties);
            var context             = new ConsumerExecutionContext(this._onMessage, messageReceivedInfo, messsageProperties, body, this);

            this._consumerDispatcher.QueueAction(() => this._handlerRunner.InvokeOnMessageHandler(context));
        }
Пример #4
0
 /// <summary>
 /// 发布消息
 /// </summary>
 /// <param name="exchange"></param>
 /// <param name="routingKey"></param>
 /// <param name="mandatory">当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者;当mandatory设为false时,出现上述情形broker会直接将消息扔掉。</param>
 /// <param name="immediate">当immediate标志位设置为true时,如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。</param>
 /// <param name="messageProperties"></param>
 /// <param name="body"></param>
 /// <returns></returns>
 public void Publish(IExchange exchange, string routingKey, bool mandatory, bool immediate, MessageProperties messageProperties, byte[] body)
 {
     Preconditions.CheckNotNull(exchange, "exchange");
     this.Publish(exchange.Name, routingKey, mandatory, immediate, messageProperties, body);
 }
Пример #5
0
 /// <summary>
 /// 发布消息
 /// </summary>
 /// <param name="exchange"></param>
 /// <param name="routingKey"></param>
 /// <param name="messageProperties"></param>
 /// <param name="body"></param>
 public void Publish(IExchange exchange, string routingKey, MessageProperties messageProperties, byte[] body)
 {
     this.Publish(exchange, routingKey, false, false, messageProperties, body);
 }
Пример #6
0
        /// <summary>
        /// 发布消息
        /// http://www.sjsjw.com/kf_jiagou/article/023563ABA032194.asp
        /// </summary>
        /// <param name="exchange"></param>
        /// <param name="routingKey"></param>
        /// <param name="mandatory">当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者;当mandatory设为false时,出现上述情形broker会直接将消息扔掉。</param>
        /// <param name="immediate">当immediate标志位设置为true时,如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。</param>
        /// <param name="messageProperties"></param>
        /// <param name="body"></param>
        /// <returns></returns>
        private void PublishAsync(string exchange, string routingKey, bool mandatory, bool immediate, MessageProperties messageProperties, byte[] body)
        {
            Preconditions.CheckNotNull(exchange, "exchange");
            Preconditions.CheckShortString(routingKey, "routingKey");
            Preconditions.CheckNotNull(body, "body");

            this._clientCommandDispatcher.Invoke(x =>
            {
                IBasicProperties basicProperties = null;
                if (messageProperties != null)
                {
                    basicProperties = x.CreateBasicProperties();
                    messageProperties.CopyTo(basicProperties);
                }
                this._publisher.Publish(x, body, messageProperties, (m, b, p) => m.BasicPublish(exchange, routingKey, mandatory, immediate, basicProperties, body));
            }).Wait();

            ConsoleLogger.DebugWrite("Published to exchange: '{0}', routing key: '{1}', correlationId: '{2}'", exchange, routingKey, messageProperties == null ? "null" : messageProperties.CorrelationId);
        }
Пример #7
0
 /// <summary>
 /// 发布消息
 /// </summary>
 /// <param name="exchange"></param>
 /// <param name="routingKey"></param>
 /// <param name="mandatory">当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者;当mandatory设为false时,出现上述情形broker会直接将消息扔掉。</param>
 /// <param name="immediate">当immediate标志位设置为true时,如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。</param>
 /// <param name="messageProperties"></param>
 /// <param name="body"></param>
 public void Publish(string exchange, string routingKey, bool mandatory, bool immediate, MessageProperties messageProperties, byte[] body)
 {
     try
     {
         this.PublishAsync(exchange, routingKey, mandatory, immediate, messageProperties, body);
     }
     catch (AggregateException aggregateException)
     {
         throw aggregateException.InnerException;
     }
 }
Пример #8
0
        /// <summary>
        /// 发布(执行),等同于 执行Onclick方法(执行委托所关联的方法)
        /// 正确理解的理解方式是,通道(model)要执行的方法,相当于model.pubishAction()。此处分开写了,model一个参数,publishAction一个参数。
        /// </summary>
        /// <param name="model">通道对象</param>
        /// <param name="publishAction">要执行的方法,参数就是model通道。</param>
        /// <returns></returns>
        public override void Publish(IModel model, byte[] body, MessageProperties messageProperties, Action <IModel, byte[], MessageProperties> publishAction)
        {
            base.SetModel(model);

            publishAction(model, body, messageProperties);
        }
Пример #9
0
 /// <summary>
 /// 发布(执行),等同于 执行Onclick方法(执行委托所关联的方法)
 /// 正确理解的理解方式是,通道(model)要执行的方法,相当于model.pubishAction()。此处分开写了,model一个参数,publishAction一个参数。
 /// </summary>
 /// <param name="model">通道对象</param>
 /// <param name="publishAction">要执行的方法,参数就是model通道。</param>
 /// <returns></returns>
 public abstract void Publish(IModel model, byte[] body, MessageProperties messageProperties, Action <IModel, byte[], MessageProperties> publishAction);