Esempio n. 1
0
        public static SubAckPacket AddSubscriptions(ISessionState session, SubscribePacket packet, QualityOfService maxSupportedQos)
        {
            List <Subscription> subscriptions = session.Subscriptions;
            var returnCodes = new List <QualityOfService>(subscriptions.Count);

            foreach (SubscriptionRequest request in packet.Requests)
            {
                Subscription existingSubscription = null;
                for (int i = subscriptions.Count - 1; i >= 0; i--)
                {
                    Subscription subscription = subscriptions[i];
                    if (subscription.TopicFilter.Equals(request.TopicFilter, StringComparison.Ordinal))
                    {
                        subscriptions.RemoveAt(i);
                        existingSubscription = subscription;
                        break;
                    }
                }

                QualityOfService finalQos = request.QualityOfService < maxSupportedQos ? request.QualityOfService : maxSupportedQos;

                subscriptions.Add(existingSubscription == null
                    ? new Subscription(request.TopicFilter, request.QualityOfService)
                    : existingSubscription.CreateUpdated(finalQos));

                returnCodes.Add(finalQos);
            }
            var ack = new SubAckPacket
            {
                PacketId    = packet.PacketId,
                ReturnCodes = returnCodes
            };

            return(ack);
        }
Esempio n. 2
0
        static void DecodeSubscribePayload(DataReader reader, SubscribePacket packet, ref uint remainingLength)
        {
            var subscribeTopics = new List <SubscriptionRequest>();

            while (remainingLength > 0)
            {
                string topicFilter = DecodeString(reader, ref remainingLength);
                ValidateTopicFilter(topicFilter);

                DecreaseRemainingLength(ref remainingLength, 1);
                var qos = reader.ReadByte();
                if (qos >= (int)QualityOfService.Reserved)
                {
                    throw new DecoderException($"[MQTT-3.8.3-4]. Invalid QoS value: {qos}.");
                }

                subscribeTopics.Add(new SubscriptionRequest(topicFilter, (QualityOfService)qos));
            }

            if (subscribeTopics.Count == 0)
            {
                throw new DecoderException("[MQTT-3.8.3-3]");
            }

            packet.Requests = subscribeTopics;
        }
Esempio n. 3
0
        static void DecodeSubscribePayload(IByteBuffer buffer, SubscribePacket packet, ref int remainingLength)
        {
            const int ReservedQos     = (int)QualityOfService.Reserved;
            var       subscribeTopics = new List <SubscriptionRequest>();

            while (remainingLength > 0)
            {
                string topicFilter = DecodeString(buffer, ref remainingLength);
                ValidateTopicFilter(topicFilter);

                DecreaseRemainingLength(ref remainingLength, 1);
                int qos = buffer.ReadByte();
                if (qos >= ReservedQos)
                {
                    ThrowHelper.ThrowDecoderException_MQTT_383_4(qos);
                }

                subscribeTopics.Add(new SubscriptionRequest(topicFilter, (QualityOfService)qos));
            }

            if (0u >= (uint)subscribeTopics.Count)
            {
                ThrowHelper.ThrowDecoderException_MQTT_383_3();
            }

            packet.Requests = subscribeTopics;
        }
Esempio n. 4
0
        public async Task <string> InternalSubscribeAsync(string subject, string queueGroup,
                                                          Func <NATSMsgSubscriptionConfig, SubscriptionMessageHandler> messageHandlerSetup, int?maxMsg = null, string subscribeId = null)
        {
            await ConnectAsync();

            var SubscribeId = subscribeId ?? $"sid{Interlocked.Increment(ref _subscribeId)}";

            _logger.LogDebug($"设置订阅消息队列订阅编号 Subject = {subject} QueueGroup = {queueGroup} SubscribeId = {SubscribeId}");

            var SubscriptionConfig = new NATSMsgSubscriptionConfig(subject, SubscribeId, queueGroup, maxMsg);

            //处理订阅响应的管道
            var messageHandler = messageHandlerSetup(SubscriptionConfig);

            _logger.LogDebug($"开始添加消息队列处理器 Subject = {subject} QueueGroup = {queueGroup} SubscribeId = {SubscribeId}");

            //添加订阅响应管道
            _embed_channel.Pipeline.AddLast(messageHandler);

            _logger.LogDebug($"结束添加消息队列处理器 Subject = {subject} QueueGroup = {queueGroup} SubscribeId = {SubscribeId}");


            _logger.LogDebug($"开始发送订阅请求 订阅主题 {subject } 订阅编号 {SubscribeId}");

            var SubscribePacketMsg = new SubscribePacket(SubscribeId, subject, queueGroup);

            await _embed_channel.WriteAndFlushAsync(SubscribePacketMsg);

            _logger.LogDebug($"结束发送订阅请求 订阅主题 {subject } 订阅编号 {SubscribeId}");

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

            return(SubscribeId);
        }
        async Task SubscribeAsync(IChannelHandlerContext context, SubscribePacket packetPassed)
        {
            string           topicFilter;
            QualityOfService qos;

            if (packetPassed == null || packetPassed.Requests == null)
            {
                topicFilter = topicFilter = CommandTopicFilterFormat.FormatInvariant(this.deviceId);
                qos         = mqttTransportSettings.ReceivingQoS;
            }
            else if (packetPassed.Requests.Count == 1)
            {
                topicFilter = packetPassed.Requests[0].TopicFilter;
                qos         = packetPassed.Requests[0].QualityOfService;
            }
            else
            {
                throw new ArgumentException("unexpected request count.  expected 1, got " + packetPassed.Requests.Count.ToString());
            }


            int packetId        = Util.GetNextPacketId();
            var subscribePacket = new SubscribePacket(packetId, new SubscriptionRequest(topicFilter, qos));

            this.subscribeCompletions[packetId] = new TaskCompletionSource();

            await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler);

            await this.subscribeCompletions[packetId].Task;
        }
Esempio n. 6
0
        public async Task <string> InternalSubscribeAsync(string subject, string queueGroup,
                                                          SubscriptionMessageHandler messageHandler, string subscribeId = null)
        {
            await ConnectAsync();

            var SubscribeId = subscribeId ?? $"sid{Interlocked.Increment(ref _subscribeId)}";

            _logger.LogDebug($"开始添加消息队列处理器 Subject = {subject} QueueGroup = {queueGroup} SubscribeId = {SubscribeId}");

            //添加订阅响应管道
            _embed_channel.Pipeline.AddLast(messageHandler);

            _logger.LogDebug($"结束添加消息队列处理器 Subject = {subject} QueueGroup = {queueGroup} SubscribeId = {SubscribeId}");


            _logger.LogDebug($"开始发送订阅请求 订阅主题 {subject } 订阅编号 {SubscribeId}");

            var SubscribePacketMsg = new SubscribePacket(SubscribeId, subject, queueGroup);

            await _embed_channel.WriteAndFlushAsync(SubscribePacketMsg);

            _logger.LogDebug($"结束发送订阅请求 订阅主题 {subject } 订阅编号 {SubscribeId}");

            return(SubscribeId);
        }
Esempio n. 7
0
        public Task <IMqttResult> Subscribe(MqttClientSession clientSession, SubscribePacket subscribePacket)
        {
            if (!CLIENT_DIC.TryGetValue(clientSession.ClientId, out List <MqttSubscription> subList))
            {
                subList = new List <MqttSubscription>();

                CLIENT_DIC.TryAdd(clientSession.ClientId, subList);
            }

            foreach (SubscriptionRequest subReq in subscribePacket.Requests)
            {
                if (!subList.Exists(x => x.Topic.Equals(subReq.TopicFilter, StringComparison.OrdinalIgnoreCase)))
                {
                    subList.Add(new MqttSubscription {
                        ClientSession = clientSession,
                        Topic         = subReq.TopicFilter,
                        Qos           = subReq.QualityOfService
                    });
                }

                if (!TOPIC_DIC.TryGetValue(subReq.TopicFilter, out List <string> clientIds))
                {
                    clientIds = new List <string>();
                    TOPIC_DIC.TryAdd(subReq.TopicFilter, clientIds);
                }
                clientIds.Add(clientSession.ClientId);
            }

            return(Task.FromResult <IMqttResult>(SubscribeResult.SUCCESS));
        }
        static void EncodeSubscribeMessage(DataWriter writer, SubscribePacket packet)
        {
            const int VariableHeaderSize = PACKET_ID_LENGTH;
            int       payloadBufferSize  = 0;

            var encodedTopicFilters = new List <byte[]>();

            foreach (var topic in packet.Requests)
            {
                byte[] topicFilterBytes = EncodeStringInUtf8(topic.TopicFilter);
                payloadBufferSize += STRING_SIZE_LENGTH + topicFilterBytes.Length + 1; // length, value, QoS
                encodedTopicFilters.Add(topicFilterBytes);
            }

            int variablePartSize = VariableHeaderSize + payloadBufferSize;

            writer.WriteByte(CalculateFirstByteOfFixedHeader(packet));
            WriteVariableLengthInt(writer, variablePartSize);

            // Variable Header
            writer.WriteInt16((short)packet.PacketId);  // todo: review: validate?

            // Payload
            for (int i = 0; i < encodedTopicFilters.Count; i++)
            {
                var topicFilterBytes = encodedTopicFilters[i];
                writer.WriteInt16((short)topicFilterBytes.Length);
                writer.WriteBytes(topicFilterBytes);
                writer.WriteByte((byte)packet.Requests[i].QualityOfService);
            }
        }
Esempio n. 9
0
        private void Subscribe(SubscribePacket packet)
        {
            if (packet.PacketId == 0)
            {
                packet.PacketId = GetNextPacketId();
            }

            Send(packet);
        }
Esempio n. 10
0
        async Task SubscribeForDM()
        {
            var messageSync     = new SubscriptionRequest("/ig_message_sync", QualityOfService.AtLeastOnce);
            var sendMessageResp = new SubscriptionRequest("/ig_send_message_response", QualityOfService.AtLeastOnce);
            var subIrisResp     = new SubscriptionRequest("/ig_sub_iris_response", QualityOfService.AtLeastOnce);
            var subscribePacket = new SubscribePacket((ushort)CryptographicBuffer.GenerateRandomNumber(), messageSync, sendMessageResp, subIrisResp);

            await FbnsPacketEncoder.EncodePacket(subscribePacket, _outboundWriter);
        }
Esempio n. 11
0
        /// <summary>
        /// 订阅主题
        /// </summary>
        /// <param name="topic">主题</param>
        /// <param name="qos">服务质量等级</param>
        /// <param name="cancellationToken"></param>
        public Task SubscribeAsync(string topic, MqttQos qos, CancellationToken cancellationToken)
        {
            var packet = new SubscribePacket();

            packet.VariableHeader.PacketIdentifier = _packetIdProvider.NewPacketId();
            packet.Add(topic, qos);

            return(SendPacketAsync(packet));
        }
Esempio n. 12
0
        bool TryDecodePacket(IChannelHandlerContext context, IByteBuffer buffer, out Packet packet)
        {
            if (!buffer.IsReadable(2))
            {
                packet = null;
                return(false);
            }

            byte signature = buffer.ReadByte();

            if (!TryDecodeRemainingLength(buffer, out int remainingLength) || !buffer.IsReadable(remainingLength))
            {
                packet = null;
                return(false);
            }

            var fixedHeader = new FixedHeader(signature, remainingLength);

            switch (fixedHeader.PacketType)
            {
            case PacketType.CONNECT: packet = new ConnectPacket(); break;

            case PacketType.CONNACK: packet = new ConnAckPacket(); break;

            case PacketType.DISCONNECT: packet = new DisconnectPacket(); break;

            case PacketType.PINGREQ: packet = new PingReqPacket(); break;

            case PacketType.PINGRESP: packet = new PingRespPacket(); break;

            case PacketType.PUBACK: packet = new PubAckPacket(); break;

            case PacketType.PUBCOMP: packet = new PubCompPacket(); break;

            case PacketType.PUBLISH: packet = new PublishPacket(); break;

            case PacketType.PUBREC: packet = new PubRecPacket(); break;

            case PacketType.PUBREL: packet = new PubRelPacket(); break;

            case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break;

            case PacketType.SUBACK: packet = new SubAckPacket(); break;

            case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break;

            case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break;

            default:
                throw new DecoderException("Unsupported Message Type");
            }
            packet.FixedHeader = fixedHeader;
            packet.Decode(buffer);

            return(true);
        }
Esempio n. 13
0
        /// <summary>
        /// 订阅主题
        /// </summary>
        /// <param name="topic">主题</param>
        /// <param name="qos">服务质量等级</param>
        /// <param name="cancellationToken"></param>
        public async Task SubscribeAsync(string topic, MqttQos qos, CancellationToken cancellationToken)
        {
            var packet = new SubscribePacket
            {
                PacketId = _packetIdProvider.NewPacketId(),
            };

            packet.Add(topic, qos);
            await SendAndFlushPacketAsync(packet);
        }
Esempio n. 14
0
        /// <summary>
        /// 订阅主题
        /// </summary>
        /// <param name="topic">主题</param>
        /// <param name="qos">服务质量等级</param>
        public Task SubscribeAsync(string topic, MqttQos qos = MqttQos.AtMostOnce)
        {
            var packet = new SubscribePacket
            {
                PacketIdentifier = _packetIdentifierProvider.GetNewPacketIdentifier(),
            };

            packet.Subscribe(topic, qos);
            return(_clientChannel.WriteAndFlushAsync(packet));
        }
Esempio n. 15
0
 public async Task Subscribe(IChannelHandlerContext context, SubscribePacket packet)
 {
     if (packet != null)
     {
         var topics = packet.Requests.Select(p => p.TopicFilter).ToArray();
         await _channelService.Suscribe(await _channelService.GetDeviceId(context.Channel), topics);
         await SubAck(context, SubAckPacket.InResponseTo(packet, QualityOfService.ExactlyOnce
                                                         ));
     }
 }
Esempio n. 16
0
        public void TestSubscribeMessage(int packetId, string[] topicFilters, QualityOfService[] requestedQosValues)
        {
            var packet = new SubscribePacket(packetId, topicFilters.Zip(requestedQosValues, (topic, qos) => new SubscriptionRequest(topic, qos)).ToArray());

            SubscribePacket recoded = this.RecodePacket(packet, true, true);

            this.contextMock.Verify(x => x.FireChannelRead(It.IsAny <SubscribePacket>()), Times.Once);
            Assert.Equal(packet.Requests, recoded.Requests, EqualityComparer <SubscriptionRequest> .Default);
            Assert.Equal(packet.PacketId, recoded.PacketId);
        }
Esempio n. 17
0
        /// <summary>
        /// 订阅主题
        /// </summary>
        /// <param name="topic">主题</param>
        /// <param name="qos">服务质量等级</param>
        public Task <SubAckPacket> SubscribeAsync(string topic, MqttQos qos = MqttQos.AtMostOnce)
        {
            var packet = new SubscribePacket
            {
                PacketId = _packetIdentifierProvider.GetPacketId(),
            };

            packet.Add(topic, qos);

            return(SendAndReceiveAsync <SubAckPacket>(packet, _cancellationTokenSource.Token));
        }
        public async Task ShouldNotAssumeEventOrdering_SubscribeContinuesAfterUnsubAckReceived()
        {
            var request = new SubscribePacket(0, new SubscriptionRequest("myTopic", QualityOfService.AtMostOnce));
            Func <PacketWithId, SubAckPacket> ackFactory =
                (packet) => new SubAckPacket()
            {
                PacketId = packet.PacketId
            };

            await SendRequestAndAcknowledgementsInSpecificOrder(request, ackFactory, true).ConfigureAwait(false);
        }
Esempio n. 19
0
        public PendingSubscribe(TaskCompletionSource <object> promise, string topic, SubscribePacket packet)
        {
            Promise   = promise;
            Topic     = topic;
            Packet    = packet;
            Callbacks = new List <Action <Packet> >();

            retransmissionAction = new RetransmissionAction <SubscribePacket>()
            {
                OriginalPacket = packet
            };
        }
Esempio n. 20
0
        public void TestSubscribeMessage(ushort packetId, string[] topicFilters, MqttQos[] requestedQosValues)
        {
            var packet = new SubscribePacket();

            packet.VariableHeader.PacketIdentifier = packetId;
            packet.AddRange(topicFilters.Zip(requestedQosValues, (topic, qos) => new SubscribeRequest(topic, qos)).ToArray());

            SubscribePacket recoded = RecodePacket(packet, true, true);

            contextMock.Verify(x => x.FireChannelRead(It.IsAny <SubscribePacket>()), Times.Once);
            //Assert.Equal(packet.Requests, recoded.Requests, EqualityComparer<SubscribeRequest>.Default);
            //Assert.Equal(packet.PacketId, recoded.PacketId);
        }
        public async Task ShouldNotAssumeEventOrdering_SubscribeContinuesBeforeSubAckReceived()
        {
            var request = new SubscribePacket(0, new SubscriptionRequest("myTopic", QualityOfService.AtMostOnce));
            Func <PacketWithId, SubAckPacket> ackFactory =
                (packet) =>
            {
                return(new SubAckPacket()
                {
                    PacketId = packet.PacketId
                });
            };

            await SendRequestAndAcksInSpecificOrderAsync(request, ackFactory, false).ConfigureAwait(false);
        }
Esempio n. 22
0
    public void Process(SubscribePacket packet, NetPeer peer)
    {
        Channel channel;

        if (ChannelManager.Global.Channels.ContainsKey(packet.Channel))
        {
            channel = ChannelManager.Global.Channels[packet.Channel];
        }
        else
        {
            channel = new Channel(packet.Channel);
        }

        channel.Subscibers.Add(peer);
        Logger.Log($"{peer.EndPoint} subscibed to {packet.Channel}.");
    }
Esempio n. 23
0
        static void DecodeSubscribePayload(IByteBuffer buffer, SubscribePacket packet, ref int remainingLength)
        {
            while (remainingLength > 0)
            {
                string topicFilter = DecodeString(buffer, ref remainingLength);
                ValidateTopicFilter(topicFilter);

                DecreaseRemainingLength(ref remainingLength, 1);
                int qos = buffer.ReadByte();
                //if (qos >= (int)MqttQos.Reserved)
                //{
                //    throw new DecoderException($"[MQTT-3.8.3-4]. Invalid QoS value: {qos}.");
                //}

                packet.Add(new SubscriptionRequest(topicFilter, (MqttQos)qos));
            }
        }
Esempio n. 24
0
        static void EncodeSubscribeMessage(IByteBufferAllocator bufferAllocator, SubscribePacket packet, List <object> output)
        {
            const int VariableHeaderSize = PacketIdLength;
            int       payloadBufferSize  = 0;

            ThreadLocalObjectList encodedTopicFilters = ThreadLocalObjectList.NewInstance();

            IByteBuffer buf = null;

            try
            {
                foreach (SubscriptionRequest topic in packet.Requests)
                {
                    byte[] topicFilterBytes = EncodeStringInUtf8(topic.TopicFilter);
                    payloadBufferSize += StringSizeLength + topicFilterBytes.Length + 1; // length, value, QoS
                    encodedTopicFilters.Add(topicFilterBytes);
                }

                int variablePartSize      = VariableHeaderSize + payloadBufferSize;
                int fixedHeaderBufferSize = 1 + MaxVariableLength;

                buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize);
                buf.WriteByte(CalculateFirstByteOfFixedHeader(packet));
                WriteVariableLengthInt(buf, variablePartSize);

                // Variable Header
                buf.WriteShort(packet.PacketId); // todo: review: validate?

                // Payload
                for (int i = 0; i < encodedTopicFilters.Count; i++)
                {
                    var topicFilterBytes = (byte[])encodedTopicFilters[i];
                    buf.WriteShort(topicFilterBytes.Length);
                    buf.WriteBytes(topicFilterBytes, 0, topicFilterBytes.Length);
                    buf.WriteByte((int)packet.Requests[i].QualityOfService);
                }

                output.Add(buf);
                buf = null;
            }
            finally
            {
                buf?.SafeRelease();
                encodedTopicFilters.Return();
            }
        }
Esempio n. 25
0
        Packet DecodePacketInternal(IByteBuffer buffer, byte packetSignature, ref int remainingLength)
        {
            Packet packet;
            var    fixedHeader = new FixedHeader(packetSignature, remainingLength);

            switch (fixedHeader.PacketType)
            {
            case PacketType.CONNECT: packet = new ConnectPacket(); break;

            case PacketType.CONNACK: packet = new ConnAckPacket(); break;

            case PacketType.DISCONNECT: packet = new DisconnectPacket(); break;

            case PacketType.PINGREQ: packet = new PingReqPacket(); break;

            case PacketType.PINGRESP: packet = new PingRespPacket(); break;

            case PacketType.PUBACK: packet = new PubAckPacket(); break;

            case PacketType.PUBCOMP: packet = new PubCompPacket(); break;

            case PacketType.PUBLISH: packet = new PublishPacket(); break;

            case PacketType.PUBREC: packet = new PubRecPacket(); break;

            case PacketType.PUBREL: packet = new PubRelPacket(); break;

            case PacketType.SUBSCRIBE: packet = new SubscribePacket(); break;

            case PacketType.SUBACK: packet = new SubAckPacket(); break;

            case PacketType.UNSUBSCRIBE: packet = new UnsubscribePacket(); break;

            case PacketType.UNSUBACK: packet = new UnsubscribePacket(); break;

            default:
                throw new DecoderException("Unsupported Message Type");
            }
            packet.FixedHeader = fixedHeader;
            packet.Decode(buffer);
            remainingLength = packet.RemaingLength;
            return(packet);
        }
        async Task SubscribeAsync(IChannelHandlerContext context)
        {
            if (this.IsInState(StateFlags.Receiving) || this.IsInState(StateFlags.Subscribing))
            {
                return;
            }

            this.stateFlags |= StateFlags.Subscribing;

            this.subscribeCompletion = new TaskCompletionSource();

            string topicFilter = CommandTopicFilterFormat.FormatInvariant(this.deviceId);

            var subscribePacket = new SubscribePacket(Util.GetNextPacketId(), new SubscriptionRequest(topicFilter, this.mqttTransportSettings.ReceivingQoS));

            await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler);

            await this.subscribeCompletion.Task;
        }
Esempio n. 27
0
        /// <summary>
        /// Subscribes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="packet">The packet.</param>
        public async Task Subscribe(IChannelHandlerContext context, SubscribePacket packet)
        {
            if (packet != null)
            {
                var deviceId = await _channelService.GetDeviceId(context.Channel);

                var topics  = packet.Requests.Select(p => p.TopicFilter).ToArray();
                var message = TransportMessage.CreateInvokeMessage(new RemoteInvokeMessage
                {
                    ServiceId = "Subscribe", Parameters = new Dictionary <string, object> {
                        { "packet", packet }
                    }
                });
                WirteDiagnosticBefore(message, context.Channel.RemoteAddress.ToString(), deviceId, packet.PacketType);
                await _channelService.Suscribe(deviceId, topics);
                await SubAck(context, SubAckPacket.InResponseTo(packet, QualityOfService.ExactlyOnce));

                WirteDiagnosticAfter(message);
            }
        }
Esempio n. 28
0
        async Task SubscribeAsync(IChannelHandlerContext context, SubscribePacket packetPassed)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, context.Name, packetPassed, nameof(SubscribeAsync));
            }

            string           topicFilter;
            QualityOfService qos;

            if (packetPassed == null || packetPassed.Requests == null)
            {
                topicFilter = this.GetCommandTopicFilter();
                qos         = mqttTransportSettings.ReceivingQoS;
            }
            else if (packetPassed.Requests.Count == 1)
            {
                topicFilter = packetPassed.Requests[0].TopicFilter;
                qos         = packetPassed.Requests[0].QualityOfService;
            }
            else
            {
                throw new ArgumentException("unexpected request count.  expected 1, got " + packetPassed.Requests.Count.ToString());
            }

            if (!string.IsNullOrEmpty(topicFilter))
            {
                int packetId        = Util.GetNextPacketId();
                var subscribePacket = new SubscribePacket(packetId, new SubscriptionRequest(topicFilter, qos));
                this.subscribeCompletions[packetId] = new TaskCompletionSource();

                await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler).ConfigureAwait(true);

                await this.subscribeCompletions[packetId].Task.ConfigureAwait(true);
            }

            if (Logging.IsEnabled)
            {
                Logging.Exit(this, context.Name, packetPassed, nameof(SubscribeAsync));
            }
        }
        public static SubAckPacket AddSubscriptions(ISessionState session, SubscribePacket packet, QualityOfService maxSupportedQos)
        {
            IReadOnlyList <ISubscription> subscriptions = session.Subscriptions;
            var returnCodes = new List <QualityOfService>(subscriptions.Count);

            foreach (SubscriptionRequest request in packet.Requests)
            {
                QualityOfService finalQos = request.QualityOfService < maxSupportedQos ? request.QualityOfService : maxSupportedQos;

                session.AddOrUpdateSubscription(request.TopicFilter, finalQos);

                returnCodes.Add(finalQos);
            }
            var ack = new SubAckPacket
            {
                PacketId    = packet.PacketId,
                ReturnCodes = returnCodes
            };

            return(ack);
        }
Esempio n. 30
0
        public async Task SubscribeAsync(string topic, QualityOfService qos, Action <Packet> callback)
        {
            if (pendingSubscribeTopics.Contains(topic))
            {
                foreach (var subscription in pendingSubscribes.Values)
                {
                    if (subscription.Topic == topic)
                    {
                        subscription.AddCallback(callback);
                        await subscription.Promise.Task;
                        return;
                    }
                }
            }//subscribe is pending, return pending task.
            if (subscribedTopics.Contains(topic))
            {
                Subscription subscription = new Subscription(topic, callback);
                topicSubscriptions.Put(topic, subscription);
                callbackSubscriptions.Put(callback, subscription);
                return;//channel.newSucceededFuture()?
            }//already subscribed, add callback to topic's subscription.
            //send SubscribePacket and complete Task when SubAck received.
            TaskCompletionSource <object> future = new TaskCompletionSource <object>();
            SubscribePacket subscribePacket      = new SubscribePacket(PacketIdProvider.NewPacketId(), new SubscriptionRequest(topic, qos));

            var pendingSubscription = new PendingSubscribe(future, topic, subscribePacket);

            pendingSubscription.AddCallback(callback);
            pendingSubscribes.TryAdd(subscribePacket.PacketId, pendingSubscription);
            pendingSubscribeTopics.Add(topic);
            var result = await sendAndFlushAsync(subscribePacket);

            pendingSubscription.Sent = result.Success;//If not sent, we will send it when the connection is opened

            pendingSubscription.Retransmit(eventLoopGroup.GetNext(), sendAndFlushAsync);

            await future.Task;
        }