Exemple #1
0
        /// <summary>
        /// 监听延迟队列,并使用回调函数处理
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="queue">队列名</param>
        /// <param name="callback">获得队列数据时的回调函数</param>
        /// <param name="errorCallback">获取并处理队列数据出现异常时的回调函数</param>
        public void DelayWaitQueue <T>(string queue,
                                       QueueCallback <T> callback, QueueErrorCallback errorCallback = null)
        {
            if (string.IsNullOrEmpty(queue))
            {
                throw new ArgumentException("队列名不能为空", nameof(queue));
            }
            //var deadRoutingKey = queue + ".DeadRoute";
            var deadQueue = queue + ".DeadLetter";

            WaitQueue(deadQueue, callback, errorCallback);
        }
Exemple #2
0
 /// <summary>
 /// 监听队列,并使用回调函数处理
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="queue">队列名</param>
 /// <param name="consumerNum">启动几个消费者</param>
 /// <param name="callback">获得队列数据时的回调函数</param>
 /// <param name="errorCallback">获取并处理队列数据出现异常时的回调函数</param>
 /// <param name="prefetchCount">每个消费者的消息预取数量,默认5条,超过5个未ack时,不接收消息</param>
 /// <param name="useAsync">异步处理消息还是同步</param>
 public void WaitQueue <T>(string queue, int consumerNum,
                           QueueCallback <T> callback, QueueErrorCallback errorCallback = null,
                           ushort prefetchCount = 0, bool useAsync = false)
 {
     if (consumerNum < 1)
     {
         throw new ArgumentException("消费者数量不能小于1");
     }
     for (var i = 0; i < consumerNum; i++)
     {
         WaitQueue(queue, callback, errorCallback, prefetchCount, useAsync);
     }
 }
Exemple #3
0
        /// <summary>
        /// 监听队列,并使用回调函数处理(不反序列化,带routekey)
        /// </summary>
        /// <param name="queue"></param>
        /// <param name="callback">参数1:数据, 参数2:路由, 参数3:header</param>
        /// <param name="errorCallback">异常回调方法</param>
        /// <param name="prefetchCount">预取消息数</param>
        /// <param name="useAsync">是否异步处理收到的消息</param>
        public void WaitQueueWithRouteKey(string queue,
                                          Action <string, string, IDictionary <string, object> > callback,
                                          QueueErrorCallback errorCallback = null,
                                          ushort prefetchCount             = 0, bool useAsync = false)
        {
            if (string.IsNullOrEmpty(queue))
            {
                throw new ArgumentException("队列名不能为空", nameof(queue));
            }
            errorCallback = errorCallback ?? WaitErrorCallback;
            if (prefetchCount <= 0)
            {
                prefetchCount = WaitPrefetchCount;
            }
            try
            {
                // 要监听队列,所以不能关闭channel通道
                var channel = GetChannel();
                channel.BasicQos(0, prefetchCount, false);

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (sender, e) =>
                {
                    void msgCallback(object nullobj)
                    {
                        try
                        {
                            ReceiveContext(e.BasicProperties.Headers);
                            if (callback == null)
                            {
                                return;
                            }
                            callback(Utf8.GetString(e.Body), e.RoutingKey, e.BasicProperties.Headers);
                        }
                        catch (Exception exp)
                        {
                            if (errorCallback == null)
                            {
                                throw;
                            }
                            errorCallback(exp);
                            //Console.WriteLine("队列接收处理出错:" + exp.ToString());
                        }
                        finally
                        {
                            try
                            {
                                // 手工ack 参数2:multiple:是否批量.true:将一次性ack所有小于deliveryTag的消息
                                ((EventingBasicConsumer)sender).Model.BasicAck(e.DeliveryTag, false);
                            }
                            catch (Exception ackExp)
                            {
                                if (errorCallback == null)
                                {
                                    throw;
                                }
                                errorCallback(ackExp);
                            }
                            finally
                            {
                                NLogHelper.Default.Debug($"Event Received. Queue:{queue},Message:{Utf8.GetString(e.Body)}");
                            }
                        }
                    }

                    if (useAsync)
                    {
                        ThreadPool.UnsafeQueueUserWorkItem(msgCallback, null);
                    }
                    else
                    {
                        msgCallback(null);
                    }
                };
                // 开启acknowledge机制,在接收事件里ack,配合qos进行流控
                channel.BasicConsume(queue, false, consumer);
            }
            catch (Exception exp)
            {
                if (errorCallback == null)
                {
                    throw;
                }
                errorCallback(exp);
                //Console.WriteLine("队列接收处理出错:" + exp.ToString());
            }
        }
Exemple #4
0
        ///// <summary>
        ///// 监听队列,并使用回调函数处理
        ///// </summary>
        ///// <param name="queue">队列名</param>
        ///// <param name="callback">获得队列数据时的回调函数</param>
        ///// <param name="errorCallback">获取并处理队列数据出现异常时的回调函数</param>
        //[Obsolete("请改用WaitQueue<T>方法")]
        //public void WaitQueue(string queue,
        //    QueueCallback callback, QueueErrorCallback errorCallback = null)
        //{
        //    if (string.IsNullOrEmpty(queue))
        //    {
        //        throw new ArgumentException("队列名不能为空", nameof(queue));
        //    }
        //    errorCallback = errorCallback ?? WaitErrorCallback;

        //    ThreadPool.UnsafeQueueUserWorkItem(state =>
        //    {
        //        try
        //        {
        //            // 要监听队列,所以不能关闭channel通道
        //            var channel = GetChannel();
        //            var consumer = new EventingBasicConsumer(channel);
        //            consumer.Received += (sender, e) =>
        //            {
        //                try
        //                {
        //                    callback?.Invoke(e.Body, e.BasicProperties.Headers);
        //                }
        //                catch (Exception exp)
        //                {
        //                    if (errorCallback == null)
        //                        throw;
        //                    errorCallback(exp);
        //                    //Console.WriteLine("队列接收处理出错:" + exp.ToString());
        //                }
        //            };
        //            channel.BasicConsume(queue, true, consumer);
        //        }
        //        catch (Exception exp)
        //        {
        //            if (errorCallback == null)
        //                throw;
        //            errorCallback(exp);
        //            //Console.WriteLine("队列接收处理出错:" + exp.ToString());
        //        }
        //    }, callback);
        //}


        /// <summary>
        /// 监听队列,并使用回调函数处理
        /// </summary>
        /// <param name="queue">队列名</param>
        /// <param name="callback">获得队列数据时的回调函数</param>
        /// <param name="errorCallback">获取并处理队列数据出现异常时的回调函数</param>
        /// <param name="prefetchCount">消息预取数量,默认5条,超过5个未ack时,不接收消息</param>
        /// <param name="useAsync">异步处理消息还是同步</param>
        public void WaitQueue(string queue,
                              QueueCallback <string> callback, QueueErrorCallback errorCallback = null,
                              ushort prefetchCount = 0, bool useAsync = false)
        {
            WaitQueue <string>(queue, callback, errorCallback, prefetchCount, useAsync);
        }