Example #1
0
        public override bool Connect(string deviceId, MqttChannel channel)
        {
            var mqttChannel = GetMqttChannel(deviceId);

            if (mqttChannel != null)
            {
                if (mqttChannel.IsOnine())
                {
                    return(false);
                }
                else if (!mqttChannel.IsOnine())
                {
                    if (mqttChannel.SubscribeStatus == SubscribeStatus.Yes)
                    {
                        var topics = RemoveSubTopic(mqttChannel);
                        foreach (var topic in topics)
                        {
                            Topics.TryGetValue(topic, out IEnumerable <MqttChannel> comparisonValue);
                            var newValue = comparisonValue.Concat(new[] { channel });
                            Topics.AddOrUpdate(topic, newValue, (key, value) => newValue);
                        }
                    }
                }
            }
            MqttChannels.AddOrUpdate(deviceId, channel, (k, v) => channel);
            return(true);
        }
        public MqttChannel GetMqttChannel(string deviceId)
        {
            MqttChannel channel = null;

            if (!string.IsNullOrEmpty(deviceId))
            {
                _mqttChannels.TryGetValue(deviceId, out channel);
            }
            return(channel);
        }
Example #3
0
        public IEnumerable <String> RemoveSubTopic(MqttChannel mqttChannel)
        {
            IEnumerable <String> topics = mqttChannel.Topics;

            foreach (var topic in topics)
            {
                Topics.TryGetValue(topic, out IEnumerable <MqttChannel> comparisonValue);
                var newValue = comparisonValue.Where(p => p != mqttChannel);
                Topics.TryUpdate(topic, newValue, comparisonValue);
            }
            return(topics);
        }
Example #4
0
        /// <summary>
        /// Sends the pub record.
        /// </summary>
        /// <param name="mqttChannel">The MQTT channel.</param>
        /// <param name="messageId">The message identifier.</param>
        public async Task SendPubRec(MqttChannel mqttChannel, int messageId)
        {
            var mqttPubAckMessage = new PubRecPacket
            {
                PacketId = messageId
            };
            var channel = mqttChannel.Channel;
            await channel.WriteAndFlushAsync(mqttPubAckMessage);

            var sendMqttMessage = Enqueue(channel, messageId, null, null, 1, ConfirmStatus.PUBREC);

            mqttChannel.AddMqttMessage(messageId, sendMqttMessage);
        }
        public bool RemoveChannel(string topic, MqttChannel mqttChannel)
        {
            var result = false;

            if (!string.IsNullOrEmpty(topic) && mqttChannel != null)
            {
                _topics.TryGetValue(topic, out IEnumerable <MqttChannel> mqttChannels);
                var channels = mqttChannels == null ? new List <MqttChannel>() : mqttChannels.ToList();
                channels.Remove(mqttChannel);
                _topics.AddOrUpdate(topic, channels, (key, value) => channels);
                result = true;
            }
            return(result);
        }
Example #6
0
 public async Task SendRetain(string topic, MqttChannel mqttChannel)
 {
     Retain.TryGetValue(topic, out ConcurrentQueue <RetainMessage> retainMessages);
     if (retainMessages != null && !retainMessages.IsEmpty)
     {
         var messages = retainMessages.GetEnumerator();
         while (messages.MoveNext())
         {
             var retainMessage = messages.Current;
             await SendMessage(mqttChannel, retainMessage.QoS, topic, retainMessage.ByteBuf);
         }
         ;
     }
 }
Example #7
0
 public async Task SendRetain(string topic, MqttChannel mqttChannel)
 {
     Retain.TryGetValue(topic, out ConcurrentQueue <RetainMessage> retainMessages);
     if (retainMessages != null && !retainMessages.IsEmpty)
     {
         var count = retainMessages.Count;
         for (int i = 0; i < count; i++)
         {
             if (retainMessages.TryDequeue(out RetainMessage retainMessage))
             {
                 await SendMessage(mqttChannel, retainMessage.QoS, topic, retainMessage.ByteBuf);
             }
         }
     }
 }
        public async Task SendQosConfirmMsg(QualityOfService qos, MqttChannel mqttChannel, string topic, byte[] bytes)
        {
            if (mqttChannel.IsLogin())
            {
                int messageId = MessageIdGenerater.GenerateId();
                switch (qos)
                {
                case QualityOfService.AtLeastOnce:
                    mqttChannel.AddMqttMessage(messageId, await SendQos1Msg(mqttChannel.Channel, topic, false, bytes, messageId));
                    break;

                case QualityOfService.ExactlyOnce:
                    mqttChannel.AddMqttMessage(messageId, await SendQos2Msg(mqttChannel.Channel, topic, false, bytes, messageId));
                    break;
                }
            }
        }
Example #9
0
        public override async Task Publish(IChannel channel, PublishPacket mqttPublishMessage)
        {
            MqttChannel mqttChannel = GetMqttChannel(await this.GetDeviceId(channel));
            var         buffer      = mqttPublishMessage.Payload;

            byte[] bytes = new byte[buffer.ReadableBytes];
            buffer.ReadBytes(bytes);
            int messageId = mqttPublishMessage.PacketId;

            if (channel.HasAttribute(LoginAttrKey) && mqttChannel != null)
            {
                bool isRetain = mqttPublishMessage.RetainRequested;
                switch (mqttPublishMessage.QualityOfService)
                {
                case QualityOfService.AtLeastOnce:
                    await _messagePushService.SendPubBack(channel, messageId);

                    break;

                case QualityOfService.ExactlyOnce:
                    await Pubrec(mqttChannel, messageId);

                    break;
                }
                if (isRetain)
                {
                    SaveRetain(mqttPublishMessage.TopicName,
                               new RetainMessage
                    {
                        ByteBuf = bytes,
                        QoS     = (int)mqttPublishMessage.QualityOfService
                    }, mqttPublishMessage.QualityOfService == QualityOfService.AtMostOnce ? true : false);
                }
                await PushMessage(mqttPublishMessage.TopicName, (int)mqttPublishMessage.QualityOfService, bytes, isRetain);
                await RemotePublishMessage("", new MqttWillMessage
                {
                    Qos         = (int)mqttPublishMessage.QualityOfService,
                    Topic       = mqttPublishMessage.TopicName,
                    WillMessage = Encoding.Default.GetString(bytes),
                    WillRetain  = mqttPublishMessage.RetainRequested
                });
            }
        }
Example #10
0
        private async Task SendMessage(MqttChannel mqttChannel, int qos, string topic, byte [] byteBuf)
        {
            switch (qos)
            {
            case 0:
                await _messagePushService.SendQos0Msg(mqttChannel.Channel, topic, byteBuf);

                break;

            case 1:
                await _messagePushService.SendQosConfirmMsg(QualityOfService.AtLeastOnce, mqttChannel, topic, byteBuf);

                break;

            case 2:
                await _messagePushService.SendQosConfirmMsg(QualityOfService.ExactlyOnce, mqttChannel, topic, byteBuf);

                break;
            }
        }
        public async Task WriteWillMsg(MqttChannel mqttChannel, MqttWillMessage willMeaasge)
        {
            switch (willMeaasge.Qos)
            {
            case 0:
                await SendQos0Msg(mqttChannel.Channel, willMeaasge.Topic, Encoding.Default.GetBytes(willMeaasge.WillMessage));

                break;

            case 1:     // qos1
                await SendQosConfirmMsg(QualityOfService.AtLeastOnce, mqttChannel, willMeaasge.Topic, Encoding.Default.GetBytes(willMeaasge.WillMessage));

                break;

            case 2:     // qos2
                await SendQosConfirmMsg(QualityOfService.ExactlyOnce, mqttChannel, willMeaasge.Topic, Encoding.Default.GetBytes(willMeaasge.WillMessage));

                break;
            }
        }
 /// <summary>
 /// Pubrecs the specified channel.
 /// </summary>
 /// <param name="channel">The channel.</param>
 /// <param name="messageId">The message identifier.</param>
 /// <returns>Task.</returns>
 public abstract Task Pubrec(MqttChannel channel, int messageId);
 /// <summary>
 /// Connects the specified device identifier.
 /// </summary>
 /// <param name="deviceId">The device identifier.</param>
 /// <param name="build">The build.</param>
 /// <returns>Task&lt;System.Boolean&gt;.</returns>
 public abstract Task <bool> Connect(string deviceId, MqttChannel build);
Example #14
0
        private async Task Init(IChannel channel, ConnectMessage mqttConnectMessage)
        {
            String deviceId = await GetDeviceId(channel);

            MqttChannel mqttChannel = new MqttChannel()
            {
                Channel         = channel,
                CleanSession    = mqttConnectMessage.CleanSession,
                ClientId        = mqttConnectMessage.ClientId,
                SessionStatus   = SessionStatus.OPEN,
                IsWill          = mqttConnectMessage.HasWill,
                SubscribeStatus = SubscribeStatus.No,
                Messages        = new ConcurrentDictionary <int, SendMqttMessage>(),
                Topics          = new List <string>()
            };

            if (Connect(deviceId, mqttChannel))
            {
                if (mqttConnectMessage.HasWill)
                {
                    if (mqttConnectMessage.WillMessage == null || string.IsNullOrEmpty(mqttConnectMessage.WillTopic))
                    {
                        if (_logger.IsEnabled(LogLevel.Error))
                        {
                            _logger.LogError($"WillMessage 和 WillTopic不能为空");
                        }
                        return;
                    }
                    var willMessage = new MqttWillMessage
                    {
                        Qos         = mqttConnectMessage.Qos,
                        WillRetain  = mqttConnectMessage.WillRetain,
                        Topic       = mqttConnectMessage.WillTopic,
                        WillMessage = Encoding.UTF8.GetString(mqttConnectMessage.WillMessage)
                    };
                    _willService.Add(mqttConnectMessage.ClientId, willMessage);
                }
                else
                {
                    _willService.Remove(mqttConnectMessage.ClientId);
                    if (!mqttConnectMessage.WillRetain && mqttConnectMessage.WillQualityOfService != 0)
                    {
                        if (_logger.IsEnabled(LogLevel.Error))
                        {
                            _logger.LogError($"WillRetain 设置为false,WillQos必须设置为AtMostOnce");
                        }
                        return;
                    }
                }
                await channel.WriteAndFlushAsync(new ConnAckPacket
                {
                    ReturnCode     = ConnectReturnCode.Accepted,
                    SessionPresent = !mqttConnectMessage.CleanSession
                });

                var sessionMessages = _clientSessionService.GetMessages(mqttConnectMessage.ClientId);
                if (sessionMessages != null && !sessionMessages.IsEmpty)
                {
                    for (; sessionMessages.TryDequeue(out SessionMessage sessionMessage) && sessionMessage != null;)
                    {
                        switch (sessionMessage.QoS)
                        {
                        case 0:
                            await _messagePushService.SendQos0Msg(channel, sessionMessage.Topic, sessionMessage.Message);

                            break;

                        case 1:
                            await _messagePushService.SendQosConfirmMsg(QualityOfService.AtLeastOnce, GetMqttChannel(deviceId), sessionMessage.Topic, sessionMessage.Message);

                            break;

                        case 2:
                            await _messagePushService.SendQosConfirmMsg(QualityOfService.ExactlyOnce, GetMqttChannel(deviceId), sessionMessage.Topic, sessionMessage.Message);

                            break;
                        }
                    }
                }
            }
        }
Example #15
0
 public override async Task Pubrec(MqttChannel channel, int messageId)
 {
     await _messagePushService.SendPubRec(channel, messageId);
 }
 public abstract bool Connect(string deviceId, MqttChannel build);