/// <summary> /// 启动mq /// </summary> /// <param name="exceptionHandler"></param> /// <returns></returns> private bool StartMq(Action <Exception> exceptionHandler = null) { try { StopMq(); RabbitMqConfig mqConfig = GetCurrentUsedRmq(); string mqConfigStr = mqConfig.ToString(); #region 获取ConnectionFactory ConnectionFactory conFactory = null; if (!_conFactoryDict.TryGetValue(mqConfigStr, out conFactory)) { //自动重连 conFactory = new ConnectionFactory() { UserName = mqConfig.UserName, Password = mqConfig.Password, VirtualHost = mqConfig.VirtualHost, HostName = mqConfig.HostIp, Port = mqConfig.Port, AutomaticRecoveryEnabled = true /*自动重连*/, NetworkRecoveryInterval = TimeSpan.FromMilliseconds(5753) }; _conFactoryDict.AddOrUpdate(mqConfigStr, conFactory, (key, oldV) => conFactory); } #endregion IConnection tempConnect = conFactory.CreateConnection(); lock (_locker) { _curUsedConnection = tempConnect; } return(true); } catch (Exception e) { exceptionHandler?.Invoke(e); return(false); } }
/// <summary> /// 启动mq /// </summary> /// <param name="exceptionHandler"></param> /// <returns></returns> private bool StartMq(Action <Exception> exceptionHandler = null) { try { StopMq(); RabbitMqConfig mqConfig = GetCurrentUsedRmq(); string mqConfigStr = mqConfig.ToString(); #region 获取ConnectionFactory ConnectionFactory conFactory = null; if (!_conFactoryDict.TryGetValue(mqConfigStr, out conFactory)) { //自动重连 conFactory = new ConnectionFactory() { UserName = mqConfig.UserName, Password = mqConfig.Password, VirtualHost = mqConfig.VirtualHost, HostName = mqConfig.HostIp, Port = mqConfig.Port, AutomaticRecoveryEnabled = true /*自动重连*/, NetworkRecoveryInterval = TimeSpan.FromMilliseconds(5753) }; _conFactoryDict.AddOrUpdate(mqConfigStr, conFactory, (key, oldV) => conFactory); } #endregion #region 创建connection channel IConnection tempConnect = conFactory.CreateConnection(); //定义连接事件 //连接阻塞的回调 tempConnect.ConnectionBlocked += ConnectionOnConnectionBlocked; //连接未阻塞的回调 tempConnect.ConnectionUnblocked += ConnectionOnConnectionUnblocked; //连接回调异常 tempConnect.CallbackException += ConnectionOnCallbackException; //连接恢复错误 tempConnect.ConnectionRecoveryError += ConnectionOnConnectionRecoveryError; //连接恢复成功 tempConnect.RecoverySucceeded += ConnectionOnRecoverySucceeded; //连接关闭 tempConnect.ConnectionShutdown += ConnectionOnConnectionShutdown; //创建channel IModel tempChannel = tempConnect.CreateModel(); lock (_locker) { _curUsedConnection = tempConnect; _curUsedChannel = tempChannel; } #endregion #region 创建exchange //判断是否需要创建exchange bool needCreateExchange = this._needToCreateExchange; if (needCreateExchange) { bool alreadyCreated = false; if (_exchangeCreatedDict.TryGetValue(mqConfigStr, out alreadyCreated) && alreadyCreated) { needCreateExchange = false; } } if (needCreateExchange) { tempChannel.ExchangeDeclare(exchange: this._exchangeName, type: this._exchangeType, durable: true, autoDelete: false, arguments: null); _exchangeCreatedDict.AddOrUpdate(mqConfigStr, true, (key, oldV) => true); } #endregion //使用的队列名,如果为空表示临时队列 string usedQueueName = string.Empty; #region 创建queue //是否需要创建队列 bool needCreateQueue = this._needToCreateQueue; bool isTempQueue = false;//是否是临时队列 if (string.IsNullOrWhiteSpace(this._queueName)) { needCreateQueue = true; usedQueueName = string.Empty; isTempQueue = true; } else { usedQueueName = this._queueName; isTempQueue = false; if (needCreateQueue) { var alreadyCreated = false; if (_queueCreateDict.TryGetValue(mqConfigStr, out alreadyCreated) && alreadyCreated) { needCreateQueue = false; } } } if (isTempQueue) { //临时队列 //2、创建queue //由MQ服务器创建一个amp.开头的(如amq.gen-JzTY20BRgKO-HjmUJj0wLg)非持久、排他、自动删除的队列 //连接断开后,服务器将删除该队列 string tempQueueName = tempChannel.QueueDeclare().QueueName; usedQueueName = tempQueueName; tempChannel.QueueBind(queue: usedQueueName, exchange: this._exchangeName, routingKey: _queueExchangeBinding, arguments: null); } else { if (needCreateQueue) { //定义创建队列时的参数 Dictionary <string, object> dictArgs = new Dictionary <string, object>(); //限制队列的最大长度,超过该长度将从队列头丢弃 dictArgs.Add("x-max-length", MaxQueueLength); tempChannel.QueueDeclare(queue: usedQueueName, durable: true, exclusive: false, autoDelete: false, arguments: dictArgs); tempChannel.QueueBind(queue: usedQueueName, exchange: this._exchangeName, routingKey: _queueExchangeBinding, arguments: null); _queueCreateDict.AddOrUpdate(mqConfigStr, true, (key, oldV) => true); } } #endregion #region 消息接收 //prefetchSize - maximum amount of content (measured in octets) that the server will deliver, 0 if unlimited //prefetchCount - maximum number of messages that the server will deliver, 0 if unlimited //global - true if the settings should be applied to the entire channel rather than each consumer //每次取一个消息,消息大小不限制 //注释掉该行,将会使用Robbin轮盘分配,使用下面这行,只有空闲的Consumer接收消息 tempChannel.BasicQos(prefetchSize: 0, prefetchCount: 5, global: false); //定义消息接收事件 EventingBasicConsumer consumer = new EventingBasicConsumer(tempChannel); consumer.Received += ConsumerOnReceived; //自动应答 tempChannel.BasicConsume(queue: usedQueueName, autoAck: true, consumer: consumer); #endregion return(true); } catch (Exception e) { exceptionHandler?.Invoke(e); return(false); } }