/// <summary> /// Выполнить регистрацию подписчика на сообщения. /// </summary> /// <typeparam name="TMessage">Тип сообщения для обработки.</typeparam> /// <param name="messageHandler">Обработчик событий.</param> /// <param name="subscriberName">Наименование секции с конфигурацией подписчика.</param> /// <param name="onUnregister">Функция обратного вызова, для отслеживания ситуации, когда произошел дисконнект.</param> public Task RegisterAsync <TMessage>( AcknowledgableMessageHandler <TMessage> messageHandler, string subscriberName, Action <bool, string>?onUnregister = null ) where TMessage : class, IMessage { return(RegisterAsync( messageHandler, _configurationManager.GetSubscriberSettings(subscriberName), onUnregister )); }
/// <summary> /// Выполнить регистрацию подписчика на сообщения. /// </summary> /// <typeparam name="TMessage">Тип сообщения для обработки.</typeparam> /// <param name="messageHandler">Обработчик сообщений.</param> /// <param name="subscriberSettings">Настройки подписчика.</param> /// <param name="onUnregister">Функция обратного вызова, для отслеживания ситуации, когда произошел дисконнект.</param> public async Task RegisterAsync <TMessage>( AcknowledgableMessageHandler <TMessage> messageHandler, SubscriberSettings subscriberSettings, Action <bool, string>?onUnregister = null ) where TMessage : class, IMessage { var subscriber = _subscriberFactory.GetSubscriber <TMessage>(); for (var i = 0; i < subscriberSettings.ScalingSettings.ChannelsCount; i++) { await subscriber.SubscribeAsync( messageHandler, subscriberSettings, onUnregister); } }
/// <summary> /// Выполнить регистрацию подписчика на сообщения. /// </summary> /// <typeparam name="TMessage">Тип сообщения для обработки.</typeparam> /// <param name="eventHandler">Обработчик событий.</param> /// <param name="subscriberSettings">Настройки подписчика.</param> /// <param name="onUnregister">Функция обратного вызова, для отслеживания ситуации, когда произошел дисконнект.</param> public Task RegisterAsync <TMessage>( MessageHandler <TMessage> eventHandler, SubscriberSettings subscriberSettings, Action <bool, string>?onUnregister = null ) where TMessage : class, IMessage { var handler = new AcknowledgableMessageHandler <TMessage>(message => { return(eventHandler(message) .ContinueWith <Acknowledgement>(_ => Ack.Ok)); }); return(RegisterAsync( handler, subscriberSettings, onUnregister )); }
/// <summary> /// Подписаться на сообщения. /// </summary> /// <param name="messageHandler">Обработчик сообщений.</param> /// <param name="settings">Настройки очереди.</param> /// <param name="onUnsubscribed"> /// Функция обратного вызова, для отслеживания ситуации, когда остановлено потребление сообщений. /// </param> /// <returns>Канал, на котором работает подписчик.</returns> /// <typeparam name="TMessage">Тип сообщения.</typeparam> public async Task <IModel> SubscribeAsync <TMessage>( AcknowledgableMessageHandler <TMessage> messageHandler, SubscriberSettings settings, Action <bool, string>?onUnsubscribed = null ) where TMessage : class, IMessage { var channel = await BindAsync <TMessage>(settings); if (settings.UsePublisherConfirms) { // создаем канал с подтверждениями публикаций сообщений channel = new PublishConfirmableChannel( channel, TimeSpan.FromSeconds(10), _logger ); } channel.BasicQos(0, settings.ScalingSettings.MessagesPerConsumer, false); // если стоит лимит на канал, то делаем глобальным. if (settings.ScalingSettings.MessagesPerChannel > 0) { channel.BasicQos(0, settings.ScalingSettings.MessagesPerChannel, true); } var queueName = _namingConvention.QueueNamingConvention(typeof(TMessage), settings); for (var i = 0; i < settings.ScalingSettings.ConsumersPerChannel; i++) { var consumer = GetBasicConsumer(channel, settings, queueName, messageHandler, onUnsubscribed); channel.BasicConsume( queue: queueName, autoAck: settings.AutoAck, exclusive: settings.Exclusive, consumer: consumer, consumerTag: _namingConvention.ConsumerTagNamingConvention(settings, channel.ChannelNumber, i) ); } channel.CallbackException += (sender, ea) => { _logger.RabbitHandlerRestarted(ea.Exception); onUnsubscribed?.Invoke(false, ea.Exception?.Message ?? "Channel callback exception."); }; channel.ModelShutdown += (sender, ea) => { // если отключаем с админки if (ea.Initiator == ShutdownInitiator.Peer && (ea.ReplyText.Contains("stop") || ea.ReplyText.Contains("Closed via management plugin"))) { _logger.RabbitHandlerForceStopped(ea); onUnsubscribed?.Invoke(true, ea.ToString()); // force } else { _logger.RabbitHandlerRestartedAfterReconnect(ea); onUnsubscribed?.Invoke(false, ea.ToString()); } }; return(channel); }