예제 #1
0
 public SubscriptionMessageSyncHandler(
     ILogger logger,
     STANSubscriptionConfig subscriptionConfig,
     Action <STANMsgContent> messageHandler,
     Func <STANSubscriptionConfig, MsgProtoPacket, bool, Task> messageAckCallback)
     : base(logger, subscriptionConfig, messageAckCallback)
 {
     _messageHandler = messageHandler;
 }
 public SubscriptionMessageAckAsynHandler(
     ILogger logger,
     STANSubscriptionConfig subscriptionConfig,
     Func <STANMsgContent, ValueTask <bool> > messageHandler,
     Func <STANSubscriptionConfig, MsgProtoPacket, bool, Task> messageAckCallback)
     : base(logger, subscriptionConfig, messageAckCallback)
 {
     _messageHandler = messageHandler;
 }
예제 #3
0
        /// <summary>
        /// 发送消息成功处理确认
        /// </summary>
        /// <param name="subscriptionConfig">订阅配置</param>
        /// <param name="msg">消息</param>
        /// <param name="isAck">是否确认</param>
        private async Task AckAsync(STANSubscriptionConfig subscriptionConfig, MsgProtoPacket msg, bool isAck = true)
        {
            if (isAck)
            {
                var _channel = await ConnectAsync();

                await _channel.WriteAndFlushAsync(new AckPacket(subscriptionConfig.AckInbox, msg.Message.Subject, msg.Message.Sequence));
            }
        }
예제 #4
0
 public ReadMessageHandler(
     STANSubscriptionConfig subscriptionConfig,
     TaskCompletionSource <Queue <STANMsgContent> > messageTaskReady,
     Func <STANSubscriptionConfig, Task> unSubscriptionCallback = null)
 {
     _subscriptionConfig     = subscriptionConfig;
     _messageContents        = new Queue <STANMsgContent>();
     _messageTaskReady       = messageTaskReady;
     _unSubscriptionCallback = unSubscriptionCallback;
 }
예제 #5
0
 public SubscriptionMessageHandler(
     ILogger logger,
     STANSubscriptionConfig subscriptionConfig,
     Func <STANSubscriptionConfig, MsgProtoPacket, bool, Task> messageAckCallback,
     Func <STANSubscriptionConfig, Task> unSubscriptionCallback = null)
 {
     _logger                 = logger;
     _subscriptionConfig     = subscriptionConfig;
     _messageAckCallback     = messageAckCallback;
     _unSubscriptionCallback = unSubscriptionCallback;
     if (subscriptionConfig.MaxMsg.HasValue)
     {
         _channelRead = LimitedMessageHandler;
     }
     else
     {
         _channelRead = EndlessMessageHandler;
     }
 }
예제 #6
0
        public async Task UnSubscribeAsync(STANSubscriptionConfig subscriptionConfig)
        {
            await _policy.ExecuteAsync(async (cnt) =>
            {
                if (subscriptionConfig.IsUnSubscribe)
                {
                    return;
                }

                var _channel = await ConnectAsync();

                subscriptionConfig.IsUnSubscribe = true;

                var Packet = new UnsubscribeRequestPacket(_replyInboxId,
                                                          _config.UnsubRequests,
                                                          _clientId,
                                                          subscriptionConfig.Subject,
                                                          subscriptionConfig.AckInbox,
                                                          subscriptionConfig.DurableName);

                //发送取消订阅请求
                await _channel.WriteAndFlushAsync(Packet);
            }, new Dictionary <string, object>() { { "hld", "UnSubscribeAsync" }, { "sub", subscriptionConfig.Subject } });
        }
 public SubscriptionResponseHandler(STANSubscriptionConfig subscriptionConfig,
                                    TaskCompletionSource <SubscriptionResponsePacket> subscriptionResponseReady = null)
 {
     _subscriptionConfig        = subscriptionConfig;
     _subscriptionResponseReady = subscriptionResponseReady;
 }
예제 #8
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);
        }