Beispiel #1
0
        /// <summary>
        /// 获取channel
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public ChannelWrapper GetChannel()
        {
            GetConnlockObj.EnterUpgradeableReadLock();
            ChannelWrapper channel = null;

            try
            {
                foreach (var item in connectionList)
                {
                    channel = item.GetChannelFromPool();
                    if (channel != null)
                    {
                        return(channel);
                    }
                }


                #region 创建新连接

                ConnectionFactory cf = new ConnectionFactory()
                {
                    HostName = this._hostName
                };
                Connection newConn        = null;
                var        connectSuccess = true;
                var        reconnectCount = 0;
                do
                {
                    try
                    {
                        newConn        = (Connection)cf.CreateConnection();
                        connectSuccess = true;
                    }
                    catch (BrokerUnreachableException)
                    {
                        connectSuccess = false;
                        reconnectCount++;
                        Thread.Sleep(ReconnectWaitTime);
                    }
                }while (!connectSuccess && reconnectCount <= MaxReconnectCount);

                if (newConn == null)
                {
                    throw new BrokerUnreachableException(new Exception("Broker Unreachable"));
                }

                GetConnlockObj.EnterWriteLock();
                ConnectionWrapper connWrapper = new ConnectionWrapper(newConn);
                connectionList.Add(connWrapper);
                GetConnlockObj.ExitWriteLock();

                return(connWrapper.GetChannelFromPool());

                #endregion
            }
            finally
            {
                GetConnlockObj.ExitUpgradeableReadLock();
            }
        }
Beispiel #2
0
        /// <summary>
        /// 从channel池中获取channel. 如果没有,创建新的channel
        /// </summary>
        /// <returns></returns>
        public ChannelWrapper GetChannel()
        {
            GetChannellockObj.EnterUpgradeableReadLock();
            try
            {
                ChannelWrapper channel = this.ChannelList.FirstOrDefault(p => p.Reusable && !p.IsBusy);
                if (channel != null)
                {
                    channel.SetBusy();
                    return(channel);
                }
                else
                {
                    //创建新channel
                    GetChannellockObj.EnterWriteLock();
                    channel = this.Connection.CreateChannel();
                    if (channel != null)
                    {
                        this.ChannelList.Add(channel);
                    }
                    GetChannellockObj.ExitWriteLock();

                    return(channel);
                }
            }
            finally
            {
                GetChannellockObj.ExitUpgradeableReadLock();
            }
        }
Beispiel #3
0
        /// <summary>
        /// 创建新channel
        /// </summary>
        /// <returns></returns>
        public ChannelWrapper CreateChannel()
        {
            ChannelWrapper channel = null;

            if (this.CanCreateChannel())
            {
                try
                {
                    channel = new ChannelWrapper(this.Connection.CreateModel(), this);
                }
                catch (ConnectFailureException)
                {
                    this.SetUnreusable();
                }
                catch (AlreadyClosedException)
                {
                    this.SetUnreusable();
                }
                catch (OperationInterruptedException)
                {
                    this.SetUnreusable();
                }
            }

            return(channel);
        }
Beispiel #4
0
        /// <summary>
        /// 获取channel
        /// </summary>
        /// <returns></returns>
        public ChannelWrapper GetChannelFromPool()
        {
            ChannelWrapper channel = null;

            if (this.Reusable)
            {
                channel = this.ChannelPool.GetChannel();
                if (channel != null)
                {
                    this.SetBusy();
                }
            }

            return(channel);
        }
Beispiel #5
0
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="exchange"></param>
        /// <param name="exchangeType"></param>
        /// <param name="routingKey"></param>
        /// <param name="message"></param>
        /// <param name="isPersistent">消息是否持久化</param>
        /// <param name="isConfirm">是否等待confirm通知</param>
        public void SendMessage(string exchange, string exchangeType, string routingKey, byte[] message, bool isPersistent = false, bool isConfirm = false)
        {
            if (String.IsNullOrEmpty(exchange))
            {
                throw new ArgumentNullException("exchange");
            }
            if (String.IsNullOrEmpty(exchangeType))
            {
                throw new ArgumentNullException("exchangeType");
            }
            if (String.IsNullOrEmpty(routingKey))
            {
                throw new ArgumentNullException("routingKey");
            }
            if (message == null || message.Length < 1)
            {
                throw new ArgumentNullException("message");
            }

            #region 发送消息。如果发送失败,自动尝试多次发送

            ChannelWrapper channel      = null;
            var            success      = false;
            var            retryCount   = 0;
            Action         exceptionFun = () =>
            {
                if (channel != null)
                {
                    channel.SetNotBusy();
                    channel.SetUnreusable();
                }

                retryCount++;
                Thread.Sleep(RetryWaitTime);
            };
            Action action = () =>
            {
                try
                {
                    channel = CurrentConnnectionPool.GetChannel();

                    var realChannel = channel.Channel;
                    //为了便于规范管理和定义统一,exchange、queue、binding均由专人管理,程序中不进行创建
                    //realChannel.ExchangeDeclare(exchange, exchangeType, isPersistent, false, null);
                    if (isConfirm)
                    {
                        realChannel.ConfirmSelect();
                    }

                    var properties = realChannel.CreateBasicProperties();
                    properties.SetPersistent(isPersistent);
                    realChannel.BasicPublish(exchange, routingKey, properties, message);

                    if (isConfirm)
                    {
                        realChannel.WaitForConfirmsOrDie();
                    }
                    if (channel != null)
                    {
                        channel.SetNotBusy();
                    }
                    success = true;
                }
                catch (ConnectFailureException)
                {
                    exceptionFun();
                }
                catch (AlreadyClosedException)
                {
                    exceptionFun();
                }
                catch (OperationInterruptedException)
                {
                    exceptionFun();
                }
                catch (Exception)
                {
                    exceptionFun();
                }
            };

            do
            {
                action();
            } while (!success && retryCount <= MaxRetryCount);

            #endregion

            //始终不能成功,抛出异常
            if (!success)
            {
                throw new Exception("RabbitMQ连接异常");
            }
        }
Beispiel #6
0
        /// <summary>
        /// 接收消息
        /// </summary>
        /// <param name="queue"></param>
        /// <param name="isAck">是否发送ack确认</param>
        /// <returns></returns>
        public byte[] ReceiveMessage(string queue, bool isAck = false)
        {
            if (String.IsNullOrEmpty(queue))
            {
                throw new ArgumentNullException("queue");
            }

            #region 接收消息。如果接收失败,自动尝试多次接收

            byte[]         message = null;
            ChannelWrapper channel = null;

            var    success      = false;
            var    retryCount   = 0;
            Action exceptionFun = () =>
            {
                if (channel != null)
                {
                    channel.SetNotBusy();
                    channel.SetUnreusable();
                }

                retryCount++;
                Thread.Sleep(RetryWaitTime);
            };
            Action action = () =>
            {
                try
                {
                    channel = CurrentConnnectionPool.GetChannel();

                    var realChannel = channel.Channel;
                    //为了便于规范管理和定义统一,exchange、queue、binding均由专人管理,程序中不进行创建
                    //realChannel.QueueDeclare(queue, true, false, false, null);

                    BasicGetResult result = realChannel.BasicGet(queue, !isAck);
                    if (result != null)
                    {
                        if (isAck)
                        {
                            realChannel.BasicAck(result.DeliveryTag, false);
                        }
                        message = result.Body;
                    }

                    channel.SetNotBusy();
                    success = true;
                }
                catch (ConnectFailureException)
                {
                    exceptionFun();
                }
                catch (AlreadyClosedException)
                {
                    exceptionFun();
                }
                catch (OperationInterruptedException)
                {
                    exceptionFun();
                }
                catch (Exception)
                {
                    exceptionFun();
                }
            };

            do
            {
                action();
            } while (!success && retryCount <= MaxRetryCount);

            #endregion

            //始终不能成功,抛出异常
            if (!success)
            {
                throw new Exception("RabbitMQ连接异常");
            }

            return(message);
        }