diff --git a/GPW.CORE.Data/Const.cs b/GPW.CORE.Data/Const.cs new file mode 100644 index 0000000..e794c00 --- /dev/null +++ b/GPW.CORE.Data/Const.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public class Const + { + #region Public Fields + + public const string rPipeChRich = $"Channel_Rich"; + public const string rPipeChTimb = $"Channel_Timb"; + + #endregion Public Fields + } +} \ No newline at end of file diff --git a/GPW.CORE.Data/GPW - Backup.CORE.Data.csproj b/GPW.CORE.Data/GPW - Backup.CORE.Data.csproj new file mode 100644 index 0000000..d023de5 --- /dev/null +++ b/GPW.CORE.Data/GPW - Backup.CORE.Data.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + diff --git a/GPW.CORE.Data/GPW.CORE.Data.csproj b/GPW.CORE.Data/GPW.CORE.Data.csproj index 9c2569b..d023de5 100644 --- a/GPW.CORE.Data/GPW.CORE.Data.csproj +++ b/GPW.CORE.Data/GPW.CORE.Data.csproj @@ -7,7 +7,7 @@ - + @@ -19,6 +19,7 @@ + diff --git a/GPW.CORE.Data/MessagePipe.cs b/GPW.CORE.Data/MessagePipe.cs new file mode 100644 index 0000000..eda932a --- /dev/null +++ b/GPW.CORE.Data/MessagePipe.cs @@ -0,0 +1,158 @@ +using Microsoft.EntityFrameworkCore.Storage; +using NLog; +using StackExchange.Redis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public class MessagePipe + { + #region Public Constructors + + public MessagePipe(IConnectionMultiplexer redisConn, string channelName, bool enableLog = false) + { + _channel = channelName; + redis = redisConn; + redisDb = redis.GetDatabase(); + this.enableLog = enableLog; + // aggiungo sottoscrittore + setupSubscriber(); + } + + #endregion Public Constructors + + #region Public Events + + public event EventHandler EA_NewMessage = delegate { }; + + #endregion Public Events + + #region Public Methods + + /// + /// Invio messaggio sul canale + salvataggio in cache REDIS + /// + /// Chiave REDIS x salvare valore + /// Messaggio serializzato da inviare + public bool saveAndSendMessage(string memKey, string message) + { + bool answ = false; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + + // invio notifica tramite il canale richiesto + answ = sendMessage(message); + if (redisDb != null) + { + redisDb.StringSetAsync(memKey, message); + } + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + if (numSent.ContainsKey(memKey)) + { + numSent[memKey]++; + } + else + { + numSent.Add(memKey, 1); + } + if (enableLog || numSent[memKey] > 30) + { + Log.Info($"saveAndSendMessage| mKey {memKey} x {numSent[memKey]} | {message.Length} size | {ts.TotalMilliseconds} ms"); + + numSent[memKey] = 0; + } + return answ; + } + + /// + /// Invio messaggio sul canale + /// + /// + /// + public bool sendMessage(string newMess) + { + bool answ = false; + ISubscriber sub = redis.GetSubscriber(); + sub.Publish(_channel, newMess); + return answ; + } + + #endregion Public Methods + + #region Protected Fields + + protected static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Protected Fields + + #region Private Fields + + private bool enableLog = false; + private Dictionary numSent = new Dictionary(); + private IConnectionMultiplexer redis; + private StackExchange.Redis.IDatabase redisDb; + + #endregion Private Fields + + #region Private Properties + + /// + /// Canale associato al gestore pipeline messaggi + /// + private string _channel { get; set; } = ""; + + #endregion Private Properties + + #region Private Methods + + private void setupSubscriber() + { + ISubscriber sub = redis.GetSubscriber(); + //Subscribe to the channel named messages + sub.Subscribe(_channel, (channel, message) => + { + if (enableLog) + { + Log.Trace($"req setup ch {channel} | {message}"); + } + // messaggio + PubSubEventArgs mea = new PubSubEventArgs(message); + // se qualcuno ascolta sollevo evento nuovo valore... + if (EA_NewMessage != null) + { + EA_NewMessage(this, mea); + } + }); + if (enableLog) + { + Log.Info($"Subscribed {_channel}"); + } + } + + #endregion Private Methods + } + + public class PubSubEventArgs : EventArgs + { + #region Public Constructors + + public PubSubEventArgs(string messaggio) + { + this.newMessage = messaggio; + } + + #endregion Public Constructors + + #region Public Properties + + public string newMessage { get; set; } = ""; + + #endregion Public Properties + } +} diff --git a/GPW.CORE.SMART/Components/BottoniEntrEsc.razor.cs b/GPW.CORE.SMART/Components/BottoniEntrEsc.razor.cs index f10e479..aa5a880 100644 --- a/GPW.CORE.SMART/Components/BottoniEntrEsc.razor.cs +++ b/GPW.CORE.SMART/Components/BottoniEntrEsc.razor.cs @@ -98,7 +98,7 @@ namespace GPW.CORE.Smart.Components IdxDipendente = idxDip, Ipv4 = $"{ipv4}" }; - done= await CDService.TimbratureUpdate(currRecord); + done = await CDService.TimbratureUpdate(currRecord); } } } diff --git a/GPW.CORE.SMART/Data/CoreSmartDataService.cs b/GPW.CORE.SMART/Data/CoreSmartDataService.cs index 0e9581f..6eadf4d 100644 --- a/GPW.CORE.SMART/Data/CoreSmartDataService.cs +++ b/GPW.CORE.SMART/Data/CoreSmartDataService.cs @@ -1,8 +1,10 @@ using EgwCoreLib.Razor.Data; using EgwCoreLib.Utils; +using GPW.CORE.Data; using GPW.CORE.Data.DbModels; using GPW.CORE.Data.DTO; using Microsoft.AspNetCore.Identity.UI.Services; +using Microsoft.VisualBasic; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -51,6 +53,11 @@ namespace GPW.CORE.Smart.Data { dbController = new CORE.Data.Controllers.GPWController(configuration); } + + // init datapipe... + mPipeTimb = new MessagePipe(redisConn, Const.rPipeChTimb); + mPipeRich = new MessagePipe(redisConn, Const.rPipeChRich); + _logger.LogInformation("Avviata classe CoreSmartDataService"); } @@ -60,6 +67,16 @@ namespace GPW.CORE.Smart.Data public string CodApp { get; set; } = ""; + /// + /// Pipe messaggi richieste + /// + public MessagePipe mPipeRich { get; set; } = null!; + + /// + /// Pipe messaggi timbrature + /// + public MessagePipe mPipeTimb { get; set; } = null!; + #endregion Public Properties #region Public Methods @@ -1301,7 +1318,7 @@ namespace GPW.CORE.Smart.Data } /// - /// Inserimento richeista mancata timbratura + /// Inserimento richiesta mancata timbratura /// /// /// @@ -1315,6 +1332,8 @@ namespace GPW.CORE.Smart.Data currItem.Approv = false; // upsert! answ = dbController.TimbratureUpdate(currItem); + // invio in pipe timbratura + mPipeRich.sendMessage(JsonConvert.SerializeObject(currItem)); Log.Info($"Registrata richiesta Mancata Timbratura | idxDip {currItem.IdxDipendente} | data-ora: {currItem.DataOra} | isEntrata: {currItem.Entrata}"); // invalido la cache... await FlushRedisCache(); @@ -1347,6 +1366,8 @@ namespace GPW.CORE.Smart.Data try { answ = dbController.TimbratureUpdate(currItem); + // invio in pipe timbratura + mPipeTimb.sendMessage(JsonConvert.SerializeObject(currItem)); // invalido la cache... await ExecFlushRedisPattern($"{rKeyDailyData}:*"); } diff --git a/GPW.CORE.SMART/GPW.CORE.SMART.csproj b/GPW.CORE.SMART/GPW.CORE.SMART.csproj index 490b18e..301cc66 100644 --- a/GPW.CORE.SMART/GPW.CORE.SMART.csproj +++ b/GPW.CORE.SMART/GPW.CORE.SMART.csproj @@ -3,7 +3,7 @@ net6.0 enable - 3.0.2403.0508 + 3.0.2403.0510 enable www.egalware.com GPW Smart UI @@ -28,10 +28,10 @@ - - + + - + diff --git a/GPW.CORE.SMART/Pages/_Layout.cshtml b/GPW.CORE.SMART/Pages/_Layout.cshtml index f0d3374..c430557 100644 --- a/GPW.CORE.SMART/Pages/_Layout.cshtml +++ b/GPW.CORE.SMART/Pages/_Layout.cshtml @@ -42,7 +42,7 @@