agrobot_base/AgroBase/AgroBase/Services/MqttService.cs

250 lines
7.3 KiB
C#

using AgroBase.Forms;
using AgroBase.Models;
using AgroBase.Services;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
public class MqttService
{
private IMqttClient _client;
private IMqttClientOptions _options;
private System.Timers.Timer tmrCheck = new System.Timers.Timer() { Interval = 1000, Enabled = false };
public List<MqttTopicosModel> Topicos = new List<MqttTopicosModel>()
{
new MqttTopicosModel()
{
Topico = MapasVariaveisModel.TopicoCoordenadasGPS,
Mensagens = new List<MqttTopicosMensagensModel>(),
Inscrever = false
},
new MqttTopicosModel()
{
Topico = MapasVariaveisModel.TopicoSelecaoRuasMapa,
Mensagens = new List < MqttTopicosMensagensModel>(),
Inscrever = true
},
new MqttTopicosModel()
{
Topico = MapasVariaveisModel.TopicoTrajetoriaDinamica,
Mensagens = new List<MqttTopicosMensagensModel>(),
Inscrever = false
},
new MqttTopicosModel()
{
Topico = CamerasVaraiveisModel.TopicoEnvioBitmap,
Mensagens = new List<MqttTopicosMensagensModel>(),
Inscrever = false
}
};
public MqttService(string brokerAddress, int brokerPort)
{
var factory = new MqttFactory();
_client = factory.CreateMqttClient();
_options = new MqttClientOptionsBuilder()
.WithTcpServer(brokerAddress, brokerPort)
.WithCleanSession()
.Build();
_client.UseConnectedHandler(async e =>
{
Console.WriteLine("Connected to MQTT Broker.");
// Exemplo de inscrição em um tópico
foreach (var topic in Topicos)
{
await SubscribeAsync(topic);
}
});
_client.UseDisconnectedHandler(e =>
{
Console.WriteLine("Disconnected from MQTT Broker.");
});
_client.UseApplicationMessageReceivedHandler(e =>
{
string message = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
//Console.WriteLine($"Message received on topic {e.ApplicationMessage.Topic}");
// Aqui você pode adicionar o código para lidar com a mensagem recebida
var topico = Topicos.FirstOrDefault(x => x.Topico == e.ApplicationMessage.Topic);
if (topico != null)
{
topico.Mensagens.Add(new MqttTopicosMensagensModel()
{
Momento = DateTime.Now,
Cliente = e.ClientId,
Mensagem = message
});
if (topico.Topico == MapasVariaveisModel.TopicoSelecaoRuasMapa)
{
Variaveis.OperacaoEmAndamento.OpMapaGPS.AtualizarRuasSelecionadas();
}
else if (topico.Topico == CamerasVaraiveisModel.TopicoRecebimentoBitmap && message != "OK")
{
try
{
Bitmap bitmap = Variaveis.OperacaoEmAndamento.CameraCaminhoKinect.ExtraiImagemDaMensagem(message);
Variaveis.OperacaoEmAndamento.CameraCaminhoKinect.AtualizarBitmapTela(bitmap);
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao processar a mensagem MQTT: {ex.Message}");
}
}
}
});
tmrCheck.Elapsed += TmrCheck_Elapsed;
tmrCheck.Start();
}
private async void TmrCheck_Elapsed(object sender, EventArgs e)
{
((System.Timers.Timer)sender).Stop();
if (!_client.IsConnected)
{
await ConnectAsync();
}
Func<bool> funcao = new Func<bool>(() =>
{
frmInstancial.frmPrincipal.lblStripMqtt.Text = "MQTT: " + (_client.IsConnected ? "Conectado" : "Desconectado");
return true;
});
FuncoesGlobais.ExecutarMetodoComVerificacaoCrossThread(frmInstancial.frmPrincipal, funcao);
((System.Timers.Timer)sender).Start();
}
public bool StatusConexao()
{
return _client.IsConnected;
}
public async Task ConnectAsync()
{
try
{
await _client.ConnectAsync(_options);
}
catch (Exception ex)
{
Console.WriteLine("Erro ao tentar se conectar ao MQTT Broker: " + ex.Message);
}
}
public async Task DisconnectAsync()
{
await _client.DisconnectAsync();
}
public async Task PublishAsync(MqttTopicosModel topic, string message, bool Forcar = false)
{
if (topic.Inscrever && !Forcar)
{
return;
}
if (_client.IsConnected)
{
var payload = Encoding.UTF8.GetBytes(message);
var mqttMessage = new MqttApplicationMessageBuilder()
.WithTopic(topic.Topico)
.WithPayload(payload)
.Build();
await _client.PublishAsync(mqttMessage);
}
}
public async Task PublishAsync(MqttTopicosModel topic, byte[] payloadBytes, bool Forcar = false)
{
if (topic.Inscrever && !Forcar)
{
return;
}
if (_client.IsConnected)
{
var mqttMessage = new MqttApplicationMessageBuilder()
.WithTopic(topic.Topico)
.WithPayload(payloadBytes)
.Build();
await _client.PublishAsync(mqttMessage);
}
}
public async Task SubscribeAsync(MqttTopicosModel topic)
{
if (!topic.Inscrever)
{
return;
}
try
{
if (!_client.IsConnected)
{
await ConnectAsync();
}
await _client.SubscribeAsync(new TopicFilterBuilder().WithTopic(topic.Topico).Build());
Console.WriteLine("Subscribed to topic: " + topic.Topico);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred while subscribing from the topic: {ex.Message}");
}
}
public async Task UnsubscribeAsync(MqttTopicosModel topic)
{
if (topic == null || !topic.Inscrever)
{
return;
}
try
{
if (!_client.IsConnected)
{
await ConnectAsync();
}
await _client.UnsubscribeAsync(new string[] { topic.Topico });
Console.WriteLine("Unsubscribed from topic: " + topic.Topico);
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred while unsubscribing from the topic: {ex.Message}");
}
}
public class MqttTopicosModel
{
public string Topico { get; set; }
public List<MqttTopicosMensagensModel> Mensagens { get; set; }
public bool Inscrever { get; set; }
}
public class MqttTopicosMensagensModel
{
public DateTime Momento { get; set; }
public string Cliente { get; set; }
public string Mensagem { get; set; }
}
}