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;
using System.Data.SqlTypes;
using System.Dynamic;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using EvaPosSCOSrv;
using EvaPosSrvResp;
using GatewaySCO; using GatewaySCO;
using Serilog; using Serilog;
using Serilog.Events;
namespace Servidor.TcpGateway; namespace Servidor.TcpGateway;
public class TcpGateway public class TcpGateway
{ {
private const int GatewayPort = 6690; readonly static bool _isDebug = Log.IsEnabled(LogEventLevel.Debug);
private const string PosbcServer = "127.0.0.1"; public int GatewayPort { get; private set; } = 6690;
private const int PosbcPort = 6697; 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() public async Task Start()
{ {
try 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); TcpListener gatewayListener = new TcpListener(IPAddress.Any, GatewayPort);
gatewayListener.Start(); gatewayListener.Start();
Log.Information($"Gateway B#2 escuchando en el puerto {GatewayPort}...");
while (true) while (true)
{ {
TcpClient checClient = await gatewayListener.AcceptTcpClientAsync(); TcpClient checClient = await gatewayListener.AcceptTcpClientAsync();
IPEndPoint checEndPoint = (IPEndPoint)checClient.Client.RemoteEndPoint;
Log.Information("CHEC conectado."); Log.Information("CHEC conectado.");
Log.Information("\tDirección CHEC: {ChecAddress}", checEndPoint.Address);
Log.Information("\tPuerto CHEC: {ChecPort}", checEndPoint.Port);
_ = Task.Run(() => HandleChecClientAsync(checClient)); _ = Task.Run(() => HandleChecClientAsync(checClient));
} }
} }
...@@ -47,10 +84,13 @@ public class TcpGateway ...@@ -47,10 +84,13 @@ public class TcpGateway
try try
{ {
await posbcClient.ConnectAsync(PosbcServer, PosbcPort); await posbcClient.ConnectAsync(PosbcServer, PosbcPort);
IPEndPoint posbcEndPoint = (IPEndPoint)posbcClient.Client.RemoteEndPoint;
Log.Information("Conectado a POSBC."); 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()) using (NetworkStream posbcStream = posbcClient.GetStream())
{ {
Task receiveFromPosbcTask = ReceiveFromPosbcAndSendToChecAsync(posbcStream, checStream); Task receiveFromPosbcTask = ReceiveFromPosbcAndSendToChecAsync(posbcStream, posbcClient, checStream, checClient);
while (true) while (true)
{ {
...@@ -69,42 +109,45 @@ public class TcpGateway ...@@ -69,42 +109,45 @@ public class TcpGateway
byte[] messageBuffer = new byte[messageLength]; byte[] messageBuffer = new byte[messageLength];
// Leer el mensaje completo basado en la longitud esperada // Leer el mensaje completo basado en la longitud esperada
bytesRead = await ReadExactlyAsync(checStream, messageBuffer, messageLength); bytesRead = await ReadExactlyAsync(checStream, messageBuffer, messageLength);
//bytesRead = await checStream.ReadAsync(messageBuffer, 0, messageLength);
if (bytesRead == 0) if (bytesRead == 0)
{ {
Log.Debug("CHEC cuerpo bytesRead = 0"); Log.Debug("CHEC cuerpo bytesRead = 0");
continue; continue;
} // Si no se lee nada, continuar esperando } // 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 // Remitir mensaje a POSBC
byte[] bytesMsj = Util.ConcatenaArreglosBytes(lengthBuffer, messageBuffer); 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); await posbcStream.WriteAsync(bytesMsj, 0, bytesMsj.Length);
Log.Information($"Mensaje remitido a POSBC: {Encoding.UTF8.GetString(messageBuffer)}"); Log.Information($"Mensaje remitido a POSBC: {Encoding.UTF8.GetString(messageBuffer)}");
} }
await receiveFromPosbcTask; await receiveFromPosbcTask;
} }
} }
catch (Exception ex) 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 try
{ {
// Leer longitud del mensaje desde POSBC // Leer longitud del mensaje desde POSBC
byte[] lengthBuffer = new byte[4]; byte[] lengthBuffer = new byte[4];
int bytesRead = await ReadExactlyAsync(posbcStream, lengthBuffer, 4); int bytesRead = await ReadExactlyAsync(posbcStream, lengthBuffer, 4);
//int bytesRead = await posbcStream.ReadAsync(lengthBuffer, 0, 4);
if (bytesRead == 0) if (bytesRead == 0)
{ {
Log.Debug("POSBC cabecera bytesRead = 0"); Log.Debug("POSBC cabecera bytesRead = 0");
...@@ -115,7 +158,6 @@ public class TcpGateway ...@@ -115,7 +158,6 @@ public class TcpGateway
Log.Debug("POSBC bytes cabecera leidos {bytes}, longitud en cabecera {longitud}", bytesRead, messageLength); Log.Debug("POSBC bytes cabecera leidos {bytes}, longitud en cabecera {longitud}", bytesRead, messageLength);
byte[] messageBuffer = new byte[messageLength]; byte[] messageBuffer = new byte[messageLength];
bytesRead = await ReadExactlyAsync(posbcStream, messageBuffer, messageLength); bytesRead = await ReadExactlyAsync(posbcStream, messageBuffer, messageLength);
//bytesRead = await posbcStream.ReadAsync(messageBuffer, 0, messageLength);
Log.Debug("POSBC bytes cuerpo leidos {bytes}", bytesRead); Log.Debug("POSBC bytes cuerpo leidos {bytes}", bytesRead);
if (bytesRead == 0) if (bytesRead == 0)
{ {
...@@ -124,13 +166,28 @@ public class TcpGateway ...@@ -124,13 +166,28 @@ public class TcpGateway
} // Si no se lee nada, continuar esperando } // Si no se lee nada, continuar esperando
if (bytesRead == 0) continue; // 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 // Remitir mensaje a CHEC
byte[] bytesMsj = Util.ConcatenaArreglosBytes(lengthBuffer, messageBuffer); 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); await checStream.WriteAsync(bytesMsj, 0, bytesMsj.Length);
Log.Information($"Mensaje remitido a CHEC: {Encoding.UTF8.GetString(messageBuffer)}"); 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) catch (Exception ex)
{ {
...@@ -138,6 +195,7 @@ public class TcpGateway ...@@ -138,6 +195,7 @@ public class TcpGateway
break; break;
} }
} }
Log.Information("Terminación conexión");
} }
private async Task<int> ReadExactlyAsync(NetworkStream stream, byte[] buffer, int length) private async Task<int> ReadExactlyAsync(NetworkStream stream, byte[] buffer, int length)
...@@ -154,4 +212,6 @@ public class TcpGateway ...@@ -154,4 +212,6 @@ public class TcpGateway
} }
return totalBytesRead; return totalBytesRead;
} }
} }
{ {
"GatewayConfig": { "GatewayConfig": {
"POS": "ECO_POSBC", "POS": "POSBCTest",
"POS_comment": "Indicates the set of commands to instantiate, according to the type of POS: evapos, tests, gk, etc.",
"IpGateway": "127.0.0.1", "IpGateway": "127.0.0.1",
"IpGateway_comment": "Gateway IP, local or remote", "PortGateway": 6690,
"PortGateway": 6697, "Language": "es"
"PortGateway_comment": "Gateway IP Port",
"Language": "es",
"Language_comment": "Language code as needed by the POS application"
}, },
"POSBC": { "POSBC": {
"IpPOSBC": "127.0.0.1", "IpPOSBC": "127.0.0.1",
"PortPOSBC": 6698 "PortPOSBC": 6697
},
"POSBCTest": {
"IpPOSBC": "127.0.0.1",
"PortPOSBC": 6697
}, },
"DataGK": { "DataGK": {
"IpGkSmartPOS": "10.10.117.10", "IpGkSmartPOS": "10.10.117.10",
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
"Args": { "Args": {
"restrictedToMinimumLevel": "Verbose" "restrictedToMinimumLevel": "Verbose"
} }
}, },
{ {
"Name": "File", "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