Пример #1
0
        /// <summary>
        /// 监控消费(只消费一次)
        /// </summary>
        /// <param name="listener">消费事件</param>
        /// <param name="autoAck">是否自动确认,默认false</param>
        public void StartSignle(IListenerMessageSingle listener, bool autoAck = false)
        {
            Connect();

            // 只获取一次
            var resp = _channel.BasicGet(_queueName, autoAck);

            var result  = false;
            var message = Encoding.UTF8.GetString(resp.Body.ToArray());

            try
            {
                result = listener.Consumer(message, resp);
                if (!result)
                {
                    result = listener.FailureHandling(message, resp);
                }
            }
            catch (Exception e)
            {
                IocCollection.GetService <ILoggerFactory>().CreateLogger(listener.GetType()).LogError(e, e.Message);
                // 消费失败后处理
                try
                {
                    result = listener.FailureHandling(message, resp);
                }
                catch (Exception exception)
                {
                    IocCollection.GetService <ILoggerFactory>()
                    .CreateLogger(listener.GetType())
                    .LogError(exception, "失败处理出现异常:" + listener.GetType().FullName);
                    result = false;
                }
            }
            finally
            {
                if (!autoAck)
                {
                    if (result)
                    {
                        _channel.BasicAck(resp.DeliveryTag, false);
                    }
                    else
                    {
                        _channel.BasicReject(resp.DeliveryTag, true);
                    }
                }

                Close();
            }
        }
Пример #2
0
        /// <summary>
        /// 定时检查连接状态
        /// </summary>
        private void CheckStatsAndConnect()
        {
            // 大于0,才开起自动重连
            if (this._lastAckTimeoutRestart < 1)
            {
                return;
            }

            // 检查连接状态
            _cts = new CancellationTokenSource();
            Task.Factory.StartNew(token =>
            {
                var cancellationToken = (CancellationToken)token;
                try
                {
                    while (true)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        // 未打开、关闭状态、上一次ACK超时,则重启
                        if (_channel == null || _channel.IsClosed)
                        {
                            IocCollection.GetService <ILoggerFactory>().CreateLogger(this.GetType()).LogWarning($"发现Rabbit未连接,或已关闭,开始重新连接");
                            ReStart();
                        }
                        else if ((DateTime.Now - _lastAckAt).TotalSeconds >= _lastAckTimeoutRestart)
                        {
                            IocCollection.GetService <ILoggerFactory>().CreateLogger(this.GetType()).LogWarning($"rabbit距上一次消费过去了{(DateTime.Now - _lastAckAt).TotalSeconds}秒后没有新的消息,尝试重新连接Rabbit。");
                            ReStart();
                        }

                        Thread.Sleep(3000);
                    }
                }
                catch (Exception e)
                {
                    IocCollection.GetService <ILoggerFactory>().CreateLogger(this.GetType()).LogWarning(e.Message);
                }
            }, _cts.Token);
        }
Пример #3
0
        /// <summary>
        /// 持续消费,并检查连接状态并自动恢复
        /// </summary>
        private void Connect(IListenerMessage listener, bool autoAck = false)
        {
            Connect();

            _channel.BasicQos(0, (ushort)_consumeThreadNums, false);
            var consumer = new EventingBasicConsumer(_channel);

            consumer.Received += (model, ea) =>
            {
                bool   result  = true;
                string?message = Encoding.UTF8.GetString(ea.Body.ToArray());
                try
                {
                    listener.Consumer(message, model, ea);
                    _lastAckAt = DateTime.Now;
                }
                catch (AlreadyClosedException e) // rabbit被关闭了,重新打开链接
                {
                    ReStart();
                    //IocCollection.GetService<ILoggerFactory>()
                    //             .CreateLogger(listener.GetType())
                    //             .LogError(e, e.ToString());
                }
                catch (Exception e)
                {
                    // 全局异常处理
                    IocCollection.GetService <IGlobalException>()?.Handle(e, message);
                    // 消费失败后处理
                    //IocCollection.GetService<ILoggerFactory>()
                    //             .CreateLogger(listener.GetType())
                    //             .LogError(e, e.ToString());

                    try
                    {
                        result = listener.FailureHandling(message, model, ea);
                    }
                    catch (Exception exception)
                    {
                        //IocCollection.GetService<ILoggerFactory>()
                        //             .CreateLogger(listener.GetType())
                        //             .LogError(exception, "失败处理出现异常:" + listener.GetType().FullName);
                        result = false;
                    }
                }
                finally
                {
                    if (!autoAck)
                    {
                        if (result)
                        {
                            _channel.BasicAck(ea.DeliveryTag, false);
                        }
                        else
                        {
                            _channel.BasicReject(ea.DeliveryTag, true);
                        }
                    }
                }
            };
            // 消费者开启监听
            _channel.BasicConsume(queue: _queueName, autoAck: autoAck, consumer: consumer);
        }