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); }
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); }
/// <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); }
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); } ; } }
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; } } }
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 }); } }
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<System.Boolean>.</returns> public abstract Task <bool> Connect(string deviceId, MqttChannel build);
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; } } } } }
public override async Task Pubrec(MqttChannel channel, int messageId) { await _messagePushService.SendPubRec(channel, messageId); }
public abstract bool Connect(string deviceId, MqttChannel build);