Пример #1
0
 /// <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
                ));
 }
Пример #2
0
        /// <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);
            }
        }
Пример #3
0
        /// <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
                       ));
        }
Пример #4
0
        /// <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);
        }