/// <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(); } }
/// <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(); } }
/// <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); }
/// <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); }
/// <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连接异常"); } }
/// <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); }