Пример #1
0
        /// <summary>
        /// 订阅
        /// </summary>
        /// <param name="subject">主题</param>
        /// <param name="queueGroup">分组名称</param>
        /// <param name="persistenceName">持久化名称</param>
        /// <param name="subscribeOptions">订阅配置</param>
        /// <param name="messageHandler">消息处理</param>
        /// <returns></returns>
        private async Task <STANSubscriptionConfig> InternalSubscribeAsync(
            string subject,
            string queueGroup,
            string persistenceName,
            STANSubscribeOptions subscribeOptions,
            Func <STANSubscriptionConfig, SubscriptionMessageHandler> messageHandlerSetup)
        {
            var _channel = await ConnectAsync();

            var SubscribePacket = new SubscribePacket();

            _logger.LogDebug($"开始设置订阅消息队列收件箱 ReplyInboxId = {_replyInboxId}");

            //订阅侦听消息
            await _channel.WriteAndFlushAsync(SubscribePacket);

            _logger.LogDebug($"结束设置订阅消息队列收件箱 ReplyInboxId = {_replyInboxId}");

            var Packet = new SubscriptionRequestPacket(
                _replyInboxId,
                _config.SubRequests,
                _clientId,
                subject,
                queueGroup,
                SubscribePacket.Subject,
                subscribeOptions.MaxInFlight ?? 1024,
                subscribeOptions.AckWaitInSecs ?? 30,
                persistenceName,
                subscribeOptions.Position);

            if (subscribeOptions.StartSequence.HasValue)
            {
                Packet.Message.StartSequence = subscribeOptions.StartSequence.Value;
            }

            if (subscribeOptions.StartTimeDelta.HasValue)
            {
                Packet.Message.StartTimeDelta = subscribeOptions.StartTimeDelta.Value;
            }

            //订阅配置信息
            var SubscriptionConfig = new STANSubscriptionConfig(SubscribePacket.Id, subject, Packet.ReplyTo, Packet.Message.Inbox);

            //订阅响应任务源
            var SubscriptionResponseReady = new TaskCompletionSource <SubscriptionResponsePacket>(SubscriptionConfig);

            //处理订阅响应的管道
            var SubscriptionResponseHandler = new SubscriptionResponseHandler(SubscriptionConfig, SubscriptionResponseReady);

            //添加订阅响应管道
            _channel.Pipeline.AddLast(SubscriptionResponseHandler);

            //订阅消息处理器
            var messageHandler = messageHandlerSetup(SubscriptionConfig);

            //添加消息处理到消息处理集合
            _subscriptionMessageHandler.Add(messageHandler);

            //订阅消息处理器添加到管道
            _channel.Pipeline.AddLast(SubscribePacket.Id, messageHandler);

            _logger.LogDebug($"开始发送订阅请求 包裹主题 {Packet.Subject } 订阅主题 {Packet.Message.Subject}");

            //发送订阅请求
            await _channel.WriteAndFlushAsync(Packet);

            _logger.LogDebug($"结束发送订阅请求 包裹主题 {Packet.Subject } 订阅主题 {Packet.Message.Subject}");

            //等待订阅结果响应
            var SubscriptionResponseResult = await SubscriptionResponseReady.Task;

            //移除处理订阅响应的管道
            _channel.Pipeline.Remove(SubscriptionResponseHandler);

            //如果订阅错误,同时移除订阅消息处理管道
            if (!string.IsNullOrEmpty(SubscriptionResponseResult.Message.Error))
            {
                _channel.Pipeline.Remove(messageHandler);

                _subscriptionMessageHandler.Remove(messageHandler);

                _logger.LogError($"订阅消息发生异常 错误信息 {SubscriptionResponseResult.Message.Error}");

                //TODO:待完善异常
                throw new Exception(SubscriptionResponseResult.Message.Error);
            }

            _logger.LogDebug($"成功订阅消息 包裹主题 {Packet.Subject } 订阅主题 {Packet.Message.Subject}");

            return(SubscriptionConfig);
        }