agrobot_base/AgroBase/AgroBase/Services/FilaService.cs

164 lines
5.2 KiB
C#

using AgroBase.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static AgroBase.Models.Enuns;
namespace AgroBase.Services
{
public class FilaService
{
private static List<MensagemFilaModel> MensagensFila;
public static bool FeatureAtivada = false;
public static void Inicializar(bool Ativado)
{
MensagensFila = new List<MensagemFilaModel>();
EnviarMensagensLoop().ConfigureAwait(false);
FeatureAtivada = Ativado;
}
public static void AdicionarMensagemFila(T_Code Dispositivo, string Mensagem)
{
if (Mensagem != "")
{
MensagensFila.Add(new MensagemFilaModel()
{
Id = MensagensFila.Count + 1,
Dispositivo = Dispositivo,
Mensagem = Mensagem,
AdicionadoEm = DateTime.Now,
Enviado = false,
Recebido = false,
});
}
}
private static void MarcarMensagemEnviada(int Id)
{
var Mensagem = MensagensFila.FirstOrDefault(x => x.Id == Id);
if (Mensagem != null)
{
Console.WriteLine("Mensagem Enviada: " + Mensagem.Mensagem);
Mensagem.Enviado = true;
Mensagem.EnviadoEm = DateTime.Now;
}
}
public static void MarcarMensagemRecebida(int Id)
{
var Mensagem = MensagensFila.FirstOrDefault(x => x.Id == Id);
if (Mensagem != null)
{
Mensagem.Enviado = true;
Mensagem.Recebido = true;
Mensagem.RecebidoEm = DateTime.Now;
}
}
private static bool RealizarEnvio(MensagemFilaModel Mensagem)
{
var Dispositivo = Variaveis.DispositivosConectados.FirstOrDefault(x => x.Dispositivo == Mensagem.Dispositivo);
if (Dispositivo != null)
{
if (FeatureAtivada)
{
try
{
Dispositivo.EnviarDadosSerial(
SerialService.BeginLine +
Mensagem.Id +
SerialService.SplitMessage +
Mensagem.Mensagem +
SerialService.EndLine
);
return true;
}
catch (Exception ex)
{
Console.WriteLine("Erro ao enviar mensagem para o dispositivo " + Dispositivo.Dispositivo.ToString() + " - " + ex.Message);
return false;
}
}
else
{
Dispositivo.EnviarDadosSerial(
Mensagem.Mensagem +
SerialService.EndLine
);
MarcarMensagemRecebida(Mensagem.Id);
return true;
}
}
else
{
return false;
}
}
public static bool ExistemMensagensPendentesEnvio(T_Code Dispositivo)
{
return MensagensFila.Any(x => x.Dispositivo == Dispositivo && !x.Enviado);
}
private static bool FilaLiberada(T_Code Dispositivo)
{
// Consulta mensagens do dispositivo
var Fila = MensagensFila.Where(x => x.Dispositivo == Dispositivo).OrderBy(x => x.AdicionadoEm).ToList();
// Verifica se existe alguma mensagem que foi enviada e ainda não foi respondida
var MensagemPendente = Fila.FirstOrDefault(x => x.Enviado && !x.Recebido);
// Caso não hajam mensagens pendentes, então a fila está liberada
bool Liberado = MensagemPendente == null;
if (!Liberado)
{
// Se a mensagem pendente já foi enviada a mais de um segundo, recoloca ela na fila
if (MensagemPendente.EnviadoEm?.AddSeconds(1) < DateTime.Now)
{
MensagemPendente.Enviado = false;
MensagemPendente.AdicionadoEm = DateTime.Now;
Liberado = true;
}
}
if (Dispositivo == T_Code.Dir && Fila.Any())
{
}
return Liberado;
}
public static async Task EnviarMensagensLoop()
{
while (true)
{
var Filas = MensagensFila.Where(x => !x.Enviado).GroupBy(x => x.Dispositivo).ToList();
foreach (var Fila in Filas)
{
if (FilaLiberada(Fila.Key))
{
var Mensagem = Fila.OrderBy(x => x.AdicionadoEm).FirstOrDefault();
if (RealizarEnvio(Mensagem))
{
MarcarMensagemEnviada(Mensagem.Id);
}
}
}
await Task.Delay(10);
}
}
}
}