Commit 80ed77d5 authored by Jose Hugo Torres's avatar Jose Hugo Torres
Browse files

Maneja mensaje terminar

parent 5f1abf15
using System.Xml;
using EvaPosSCOSrv;
using EvaPosSrvAplicacion;
using EvaPosSrvAplicacionImp;
using EvaPosSrvResp;
using EvaPosSrvRespImp;
using GatewaySCO;
using Serilog;
namespace Servidor.TcpGateway;
public class MessageProcessor
{
public DirectorioAdaptadoresDTO Adaptadores { get; set; }
public CreaDirectorioCmds Comandos { get; set; }
public Sesion Sesion { get; set; }
public Presentacion Presentacion { get; set; }
public IAplicacion Aplicacion { get; set; }
public MessageProcessor()
{
string tipoPOS = Entorno<Config>.Instancia.Get().POS;
Adaptadores = IniciaDirectorioAdaptadores.Cargar().DirectorioAdaptadores;
Comandos = DirectorioCmdsFactory.CreaDirectorio(tipoPOS);
Aplicacion = new Aplicacion();
}
public void MessageFromCHEC(byte[] buffer, int length)
{
// Procesando entrada: se obtiene mensaje, con el cual se
// identifica comando que lo procesa.
TramaSCO msj = Sesion.Entrada(buffer, length);
Log.Debug("MessageProcessor CHEC-POSBC tipo {tipo}, id sesión {id}, xml \n{xml}", msj.TipoMensaje.Tipo, msj.IdSesion, msj.TextoXML);
//IComando cmd = Presentacion.Entrada(msj);
// if (cmd.Referencia == "scsns:Terminate")
// {
// }
}
// Detecta mensaje de finalización de POSBC y retorna false si lo encuentra (no continuar)
public bool MessageFromPOSBCToCHEC(byte[] buffer, int length)
{
TramaSCO msj = Sesion.Entrada(buffer, length);
Log.Debug("MessageProcessor POSBC-CHEC tipo {tipo}, id sesión {id}, xml \n{xml}", msj.TipoMensaje.Tipo, msj.IdSesion, msj.TextoXML);
// Consultar si el elemento TerminateResult está presente
// XmlDocument xmlDoc = msj.ContenidoXML;
// XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
// nsmgr.AddNamespace("schema", "http://bc.si.retail.ibm.com/POSBCSchema");
// XmlNode terminateResultNode = xmlDoc.SelectSingleNode("TerminateResult", nsmgr);
// if (terminateResultNode != null)
// {
// Log.Debug("El elemento TerminateResult está presente.");
// return false;
// }
if (msj.TextoXML.Contains("<TerminateResult>"))
{
Log.Debug("Mensaje <TerminateResult> identificado.");
return false;
}
return true;
}
}
\ No newline at end of file
using System;
using System.Data.SqlTypes;
using System.Dynamic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using EvaPosSCOSrv;
using EvaPosSrvResp;
using GatewaySCO;
using Serilog;
using Serilog.Events;
namespace Servidor.TcpGateway;
public class TcpGateway
{
private const int GatewayPort = 6690;
private const string PosbcServer = "127.0.0.1";
private const int PosbcPort = 6697;
readonly static bool _isDebug = Log.IsEnabled(LogEventLevel.Debug);
public int GatewayPort { get; private set; } = 6690;
public string PosbcServer { get; private set; } = "127.0.0.1";
public int PosbcPort { get; private set; } = 6697;
private MessageProcessor _processor = null;
public TcpGateway(int gatewayPort, string posbcServer, int posbcPort)
{
GatewayPort = gatewayPort;
PosbcServer = posbcServer;
PosbcPort = posbcPort;
GatewayPort = gatewayPort;
}
public async Task Start()
{
try
{
// Id proceso. Compilación difiere según .net usado.
int idProceso = -1;
#if NETFRAMEWORK
idProceso = Process.GetCurrentProcess().Id;
#elif (NETSTANDARD || NET5_0_OR_GREATER)
idProceso = Environment.ProcessId;
#endif
Log.Information("\n" +
" _ _ _ __ ___ _ _ __ _ _ \n" +
"/ |_| |_ / __ /__ | \\ / \\_/ __ |_) / \\ (_ |_) / \n" +
"\\_ | | |_ \\_ \\_| | \\/\\/ | | \\_/ __) |_) \\_ \n");
Log.Information("Configuración del servidor Gateway TCP:");
Log.Information("\tDirección del servidor Gateway: {ServerAddress}", IPAddress.Any);
Log.Information("\tPuerto del servidor: {ServerPort}", GatewayPort);
Log.Information("\tProtocolo: {Protocol}", ProtocolType.Tcp);
Log.Information("\tVersión framework: {version}", Environment.Version);
Log.Information("\tId proceso: {id}", idProceso);
_processor = new MessageProcessor();
TcpListener gatewayListener = new TcpListener(IPAddress.Any, GatewayPort);
gatewayListener.Start();
Log.Information($"Gateway B#2 escuchando en el puerto {GatewayPort}...");
while (true)
{
TcpClient checClient = await gatewayListener.AcceptTcpClientAsync();
IPEndPoint checEndPoint = (IPEndPoint)checClient.Client.RemoteEndPoint;
Log.Information("CHEC conectado.");
Log.Information("\tDirección CHEC: {ChecAddress}", checEndPoint.Address);
Log.Information("\tPuerto CHEC: {ChecPort}", checEndPoint.Port);
_ = Task.Run(() => HandleChecClientAsync(checClient));
}
}
......@@ -47,10 +84,13 @@ public class TcpGateway
try
{
await posbcClient.ConnectAsync(PosbcServer, PosbcPort);
IPEndPoint posbcEndPoint = (IPEndPoint)posbcClient.Client.RemoteEndPoint;
Log.Information("Conectado a POSBC.");
Log.Information("\tDirección POSBC: {PosbcAddress}", posbcEndPoint.Address);
Log.Information("\tPuerto POSBC: {PosbcPort}", posbcEndPoint.Port);
using (NetworkStream posbcStream = posbcClient.GetStream())
{
Task receiveFromPosbcTask = ReceiveFromPosbcAndSendToChecAsync(posbcStream, checStream);
Task receiveFromPosbcTask = ReceiveFromPosbcAndSendToChecAsync(posbcStream, posbcClient, checStream, checClient);
while (true)
{
......@@ -69,42 +109,45 @@ public class TcpGateway
byte[] messageBuffer = new byte[messageLength];
// Leer el mensaje completo basado en la longitud esperada
bytesRead = await ReadExactlyAsync(checStream, messageBuffer, messageLength);
//bytesRead = await checStream.ReadAsync(messageBuffer, 0, messageLength);
if (bytesRead == 0)
{
Log.Debug("CHEC cuerpo bytesRead = 0");
continue;
} // Si no se lee nada, continuar esperando
// Intercepta mensajes, procesa, y eventualmente generar modificaciones o
// mensajes al POSBC
_processor.MessageFromCHEC(messageBuffer, messageLength);
// TODO: en este punto, los resultados del _processor eventualmente
// se debería integrar a los mensajes de salida.
// Remitir mensaje a POSBC
byte[] bytesMsj = Util.ConcatenaArreglosBytes(lengthBuffer, messageBuffer);
// await posbcStream.WriteAsync(lengthBuffer, 0, 4);
// await posbcStream.WriteAsync(messageBuffer, 0, messageLength);
await posbcStream.WriteAsync(bytesMsj, 0, bytesMsj.Length);
Log.Information($"Mensaje remitido a POSBC: {Encoding.UTF8.GetString(messageBuffer)}");
}
await receiveFromPosbcTask;
}
}
catch (Exception ex)
{
Log.Error(ex, "Error manejando la conexión CHEC");
//Log.Error(ex, "Error manejando la conexión CHEC");
Log.Warning("Conexión CHEC cerrada.");
}
}
}
private async Task ReceiveFromPosbcAndSendToChecAsync(NetworkStream posbcStream, NetworkStream checStream)
private async Task ReceiveFromPosbcAndSendToChecAsync(NetworkStream posbcStream, TcpClient posbcClient, NetworkStream checStream, TcpClient checClient)
{
while (true)
bool continuar = true;
while (continuar)
{
try
{
// Leer longitud del mensaje desde POSBC
byte[] lengthBuffer = new byte[4];
int bytesRead = await ReadExactlyAsync(posbcStream, lengthBuffer, 4);
//int bytesRead = await posbcStream.ReadAsync(lengthBuffer, 0, 4);
if (bytesRead == 0)
{
Log.Debug("POSBC cabecera bytesRead = 0");
......@@ -115,7 +158,6 @@ public class TcpGateway
Log.Debug("POSBC bytes cabecera leidos {bytes}, longitud en cabecera {longitud}", bytesRead, messageLength);
byte[] messageBuffer = new byte[messageLength];
bytesRead = await ReadExactlyAsync(posbcStream, messageBuffer, messageLength);
//bytesRead = await posbcStream.ReadAsync(messageBuffer, 0, messageLength);
Log.Debug("POSBC bytes cuerpo leidos {bytes}", bytesRead);
if (bytesRead == 0)
{
......@@ -124,13 +166,28 @@ public class TcpGateway
} // Si no se lee nada, continuar esperando
if (bytesRead == 0) continue; // Si no se lee nada, continuar esperando
// Intercepta mensajes y eventualmente generar modificaciones.
// Retorna false si encuenta mensaje de terminación, se sale del ciclo y cierra sesión.
continuar = _processor.MessageFromPOSBCToCHEC(messageBuffer, messageLength);
// TODO: en este punto, los resultados del _processor eventualmente
// se debería integrar a los mensajes de salida.
// Remitir mensaje a CHEC
byte[] bytesMsj = Util.ConcatenaArreglosBytes(lengthBuffer, messageBuffer);
// await checStream.WriteAsync(lengthBuffer, 0, 4);
// await checStream.WriteAsync(messageBuffer, 0, messageLength);
await checStream.WriteAsync(bytesMsj, 0, bytesMsj.Length);
Log.Information($"Mensaje remitido a CHEC: {Encoding.UTF8.GetString(messageBuffer)}");
if (continuar == false)
{
Log.Debug("Mensaje de terminación, continuar es FALSE");
posbcStream.Close();
posbcClient.Close();
checStream.Close();
checClient.Close();
}
}
catch (Exception ex)
{
......@@ -138,6 +195,7 @@ public class TcpGateway
break;
}
}
Log.Information("Terminación conexión");
}
private async Task<int> ReadExactlyAsync(NetworkStream stream, byte[] buffer, int length)
......@@ -154,4 +212,6 @@ public class TcpGateway
}
return totalBytesRead;
}
}
{
"GatewayConfig": {
"POS": "ECO_POSBC",
"POS_comment": "Indicates the set of commands to instantiate, according to the type of POS: evapos, tests, gk, etc.",
"POS": "POSBCTest",
"IpGateway": "127.0.0.1",
"IpGateway_comment": "Gateway IP, local or remote",
"PortGateway": 6697,
"PortGateway_comment": "Gateway IP Port",
"Language": "es",
"Language_comment": "Language code as needed by the POS application"
"PortGateway": 6690,
"Language": "es"
},
"POSBC": {
"IpPOSBC": "127.0.0.1",
"PortPOSBC": 6698
"PortPOSBC": 6697
},
"POSBCTest": {
"IpPOSBC": "127.0.0.1",
"PortPOSBC": 6697
},
"DataGK": {
"IpGkSmartPOS": "10.10.117.10",
......@@ -40,7 +40,6 @@
"Args": {
"restrictedToMinimumLevel": "Verbose"
}
},
{
"Name": "File",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment