void ProcessDialog(uint clientID, IEnumerable <Message> msgs) { ActiveClientsQueue.IClientData clData = m_onlineClients.Get(clientID); if (clData == null) { return; } uint lastClMsgID = clData.LastClientMessageID; var seq = from msg in msgs where msg.ID > lastClMsgID select msg; if (seq.Any()) { uint lastSrvMsgID = clData.LastSrvMessageID; var respList = new List <Message>(seq.Count()); var clStatus = m_ndxerClientsStatus.Get(clientID) as ClientStatus; clStatus.LastSeen = DateTime.Now; clData.TimeToLive = ActiveClientsQueue.InitTimeToLive; clData.LastClientMessageID = seq.Max(m => m.ID); foreach (Message msg in seq) { Dbg.Log($"Processing dialog msg {msg.ID}: {msg.MessageCode}..."); if (m_msgProcessors.ContainsKey(msg.MessageCode)) { Message resp = m_msgProcessors[msg.MessageCode](msg, clientID); if (resp != null) { respList.Add(resp); } } } if (respList.Count > 0) { DialogEngin.AppendSrvDialog(AppPaths.GetSrvDialogFilePath(clientID), respList); AddUpload(Names.GetSrvDialogFile(clientID)); } Dbg.Assert(clData.LastClientMessageID >= lastClMsgID); clStatus.SentMsgCount += clData.LastClientMessageID - lastClMsgID; Dbg.Assert(clData.LastSrvMessageID >= lastSrvMsgID); clStatus.ReceivedMsgCount += clData.LastSrvMessageID - lastSrvMsgID; m_ndxerClientsStatus.Source.Replace(m_ndxerClientsStatus.IndexOf(clientID), clStatus); } }
Message ProcessSetInfoMessage(Message msg, uint clID) { Dbg.Assert(msg.MessageCode == Message_t.SetInfo); AppContext.LogManager.LogSysActivity($"Réception d’une mise à jour des informations Utilisateur du client {ClientStrID(clID)}", true); int ndx = m_ndxerClients.IndexOf(clID); if (ndx < 0) { AppContext.LogManager.LogSysActivity("Mise à jour des information utilisateur d'un client inexistant. Réinitialisation du client.", true); //maj du fichier gov string srvDlgFile = AppPaths.GetSrvDialogFilePath(clID); //le client n'existe pas => son fichier gov n'existe pas var clDlg = new ClientDialog(clID, ClientStatus_t.Reseted, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(srvDlgFile, clDlg); AddUpload(Path.GetFileName(srvDlgFile)); return(null); } //maj le client ClientInfo clInfo = new ClientInfo(); clInfo.SetBytes(msg.Data); var client = new HubClient(clInfo.ClientID, clInfo.ProfileID) { ContaclEMail = clInfo.ContaclEMail, ContactName = clInfo.ContactName, ContactPhone = clInfo.ContactPhone, }; m_ndxerClients.Source.Replace(ndx, client); ActiveClientsQueue.IClientData clData = m_onlineClients.Get(clID); uint msgID = clData == null ? 1 : ++clData.LastClientMessageID; return(msg.CreateResponse(msgID, Message_t.Ok)); }
void ProcessRunningClients() { var deadClients = new List <uint>(); foreach (uint clID in m_onlineClients.ClientsID) { ActiveClientsQueue.IClientData clData = m_onlineClients.Get(clID); if (clData == null) { continue; } if (--clData.TimeToLive <= TTL_DIE) { deadClients.Add(clID); } else if (clData.TimeToLive <= 0) { AppContext.LogManager.LogSysActivity($"Envoi d'un message de synchronisation au client {ClientStrID(clID)}", true); var msg = new Message(++clData.LastSrvMessageID, 0, Message_t.Sync); //delegate status update to processdialog method DialogEngin.AppendSrvDialog(AppPaths.GetSrvDialogFilePath(clID), msg); AddUpload(Names.GetSrvDialogFile(clID)); } } foreach (uint id in deadClients) { AppContext.LogManager.LogSysActivity($"Client {ClientStrID(id)} présumé déconnecté", true); m_onlineClients.Remove(id); AppContext.LogManager.CloseLogger(id); ClientClosed?.Invoke(id); } foreach (uint clID in m_onlineClients.ClientsID) { AddDownload(Names.GetClientDialogFile(clID)); } }
public void SetClientStatus(HubClient client, ClientStatus_t status) { //basculer le mode de gestion des profil vers manuel //SetProfileManagementMode(client.ProfileID , ManagementMode_t.Manual); //desactiver le client HubClient oldClient = GetProfileEnabledClient(client.ProfileID); if (status == ClientStatus_t.Enabled && oldClient != null && oldClient.ID != client.ID) { AppContext.LogManager.LogSysActivity($"Désactivation du client {ClientStrID(oldClient.ID)}", true); //maj la table des status clients var oldClStatus = m_ndxerClientsStatus.Get(oldClient.ID) as ClientStatus; int ndx = m_ndxerClientsStatus.IndexOf(oldClient.ID); oldClStatus.Status = ClientStatus_t.Disabled; m_ndxerClientsStatus.Source.Replace(ndx, oldClStatus); string oldClFilePath = AppPaths.GetSrvDialogFilePath(oldClient.ID); try { ClientDialog oldClDlg = DialogEngin.ReadSrvDialog(oldClFilePath); oldClDlg.ClientStatus = ClientStatus_t.Disabled; DialogEngin.WriteSrvDialog(oldClFilePath, oldClDlg); } catch (Exception ex) { AppContext.LogManager.LogSysError($"Lecture du fichier dialogue du client {ClientStrID(oldClient.ID)}" + ex.Message); DialogEngin.WriteSrvDialog(oldClFilePath, new ClientDialog(oldClient.ID, ClientStatus_t.Disabled, Enumerable.Empty <Message>())); } finally { AddUpload(Names.GetSrvDialogFile(oldClient.ID)); } } //maj la table des statuts clients int ndxStatus = m_ndxerClientsStatus.IndexOf(client.ID); var clStatus = m_ndxerClientsStatus.Get(client.ID) as ClientStatus; clStatus.Status = status; m_ndxerClientsStatus.Source.Replace(ndxStatus, clStatus); string filePath = AppPaths.GetSrvDialogFilePath(client.ID); try { ClientDialog clDlg = DialogEngin.ReadSrvDialog(filePath); clDlg.ClientStatus = status; DialogEngin.WriteSrvDialog(filePath, clDlg); } catch (Exception ex) { AppContext.LogManager.LogSysError($"Lecture du fichier dialogue du client {ClientStrID(client.ID)}" + ex.Message); DialogEngin.WriteSrvDialog(filePath, new ClientDialog(client.ID, status, Enumerable.Empty <Message>())); } finally { AddUpload(Names.GetSrvDialogFile(client.ID)); } }
Message ProcessSyncMessage(Message msg) { Dbg.Assert(msg.MessageCode == Message_t.Sync); var ms = new MemoryStream(msg.Data); var reader = new RawDataReader(ms, Encoding.UTF8); uint clID = reader.ReadUInt(); uint srvMsgID = reader.ReadUInt(); uint clMsgId = reader.ReadUInt(); AppContext.LogManager.LogSysActivity($"Reception d'un message de synchronisation du client {ClientStrID(clID)}", true); ActiveClientsQueue.IClientData clData = m_onlineClients.Get(clID); if (clData != null) { clData.TimeToLive = ActiveClientsQueue.InitTimeToLive; var resp = new Message(++clData.LastSrvMessageID, 0, Message_t.Null); DialogEngin.AppendSrvDialog(AppPaths.GetSrvDialogFilePath(clID), resp); AddUpload(Names.GetSrvDialogFile(clID)); //maj status var clStatus = m_ndxerClientsStatus.Get(clID) as ClientStatus; clStatus.LastSeen = DateTime.Now; ++clStatus.ReceivedMsgCount; m_ndxerClientsStatus.Source.Replace(m_ndxerClientsStatus.IndexOf(clID), clStatus); return(null); } var client = m_ndxerClients.Get(clID) as HubClient; if (client == null) { AppContext.LogManager.LogSysActivity("Réception d’une demande de synchronisation " + $"de la part d’un client inexistant ({ClientStrID(clID)}). Réinitialisation du client", true); //maj du fichier gov string srvDlgFile = AppPaths.GetSrvDialogFilePath(clID); //le client n'existe pas => son fichier gov n'existe pas var clDlg = new ClientDialog(clID, ClientStatus_t.Reseted, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(srvDlgFile, clDlg); AddUpload(Path.GetFileName(srvDlgFile)); return(null); } var status = m_ndxerClientsStatus.Get(clID) as ClientStatus; var respMsg = new Message(++srvMsgID, 0, Message_t.Null); var dlg = new ClientDialog(clID, status.Status, new Message[] { respMsg }); DialogEngin.WriteSrvDialog(AppPaths.GetSrvDialogFilePath(clID), dlg); AddUpload(Names.GetSrvDialogFile(clID)); if (status.Status == ClientStatus_t.Enabled) { ActiveClientsQueue.IClientData clientData = m_onlineClients.Add(clID); clientData.LastClientMessageID = clMsgId; clientData.LastSrvMessageID = srvMsgID; AppContext.LogManager.StartLogger(clID); } return(null); }
Message ProcessStartMessage(Message msg) { Dbg.Assert(msg.MessageCode == Message_t.Start); var reader = new RawDataReader(new MemoryStream(msg.Data), Encoding.UTF8); uint clID = reader.ReadUInt(); ClientEnvironment clEnv = ClientEnvironment.Load(reader); DateTime dtStart = reader.ReadTime(); var client = m_ndxerClients.Get(clID) as HubClient; if (client == null) { AppContext.LogManager.LogSysActivity("Réception d’une notification de démarrage " + $"de la part d’un client inexistant ({ClientStrID(clID)}). Réinitialisation du client", true); //maj du fichier gov string srvDlgFile = AppPaths.GetSrvDialogFilePath(clID); //le client n'existe pas => son fichier gov n'existe pas var clDlg = new ClientDialog(clID, ClientStatus_t.Reseted, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(srvDlgFile, clDlg); AddUpload(Path.GetFileName(srvDlgFile)); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, msg.Data)); } AppContext.LogManager.LogSysActivity("Réception d’une notification de démarrage " + $"de la part du client {ClientStrID(clID)}", true); //verifier le statut du client var clStatus = m_ndxerClientsStatus.Get(clID) as ClientStatus; if (clStatus.Status != ClientStatus_t.Enabled) { AppContext.LogManager.LogSysActivity($"Démmarage du Client { ClientStrID(clID)} non autorisé. Requête rejetée", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, msg.Data)); } //reset dlg files DialogEngin.WriteHubDialog(AppPaths.GetClientDilogFilePath(clID), clID, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(AppPaths.GetSrvDialogFilePath(clID), new ClientDialog(clID, clStatus.Status, Enumerable.Empty <Message>())); try { new NetEngin(AppContext.Settings.NetworkSettings).Upload(Urls.DialogDirURL, new string[] { AppPaths.GetClientDilogFilePath(clID), AppPaths.GetSrvDialogFilePath(clID) }); } catch (Exception ex) { AppContext.LogManager.LogSysError($"Traitement de la requête de démarrage du client {ClientStrID(clID)}: " + $"{ ex.Message}. demande ignorée, laisser le client reformuler la requête.", true); return(null); // let the cleint retry req. } AppContext.LogManager.LogSysActivity($"Client {ClientStrID(clID)} démarré le { dtStart.Date.ToShortDateString()} " + $"à { dtStart.ToLongTimeString()}", true); //verifier si l'env du client a changé UpdateClientEnvironment(clID, clEnv); //ajouter client dans running liste m_onlineClients.Add(clID, dtStart); AppContext.LogManager.StartLogger(clID); AppContext.LogManager.LogClientActivity(clID, "Démarrage"); //maj du last seen clStatus.LastSeen = dtStart; m_ndxerClientsStatus.Source.Replace(m_ndxerClientsStatus.IndexOf(clID), clStatus); ClientStarted?.Invoke(clID); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Ok, msg.Data)); }
Message ProcessNewConnectionReq(Message msg) { Dbg.Assert(msg.MessageCode == Message_t.NewConnection); //TextLogger.Info("Réception d’une nouvelle requête d’inscription."); var ms = new MemoryStream(msg.Data); var reader = new RawDataReader(ms, Encoding.UTF8); ClientInfo clInfo = ClientInfo.LoadClientInfo(reader); ClientEnvironment clEnv = ClientEnvironment.Load(reader); byte[] data = BitConverter.GetBytes(clInfo.ClientID); var profile = m_ndxerProfiles.Get(clInfo.ProfileID) as UserProfile; string reqLog = $"Réception d'une demande d’inscription émanant de {clInfo.ContactName}" + $"(ID = {ClientStrID(clInfo.ClientID)}) pour " + (profile == null ? "un profil inexistant." : $"le profil {profile.Name}."); AppContext.LogManager.LogSysActivity(reqLog, true); //verifier que le profil existe if (profile == null) { AppContext.LogManager.LogSysActivity("Lancement de la procédure d’actualisation " + "de la liste des profils sur le serveur", true); ProcessProfilesChange(); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.InvalidProfile, data)); } //verifier que ClientID n'existe pas var clSameID = m_ndxerClients.Get(clInfo.ClientID) as HubClient; if (clSameID != null) { AppContext.LogManager.LogSysActivity("Collision d’identifiants: " + $"un client portant le même ID est déjà enregistré ({clSameID.ContactName}). " + "Exiger au client de reformuler son inscription avec un nouvel ID", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.InvalidID, data)); } //verifier que le profile est en mode auto ManagementMode_t prfMgmntMode = GetProfileManagementMode(clInfo.ProfileID); if (prfMgmntMode == ManagementMode_t.Manual) { AppContext.LogManager.LogSysActivity("Profil en gestion manuelle, inscription rejetée.", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, data)); } TextLogger.Info("Profil en gestion automatique."); TextLogger.Info("Enregistrement du client..."); //desactiver l'ancien client actif si il existe var oldClient = GetProfileEnabledClient(clInfo.ProfileID); if (oldClient != null) { if (IsClientRunning(oldClient.ID)) { //rejeter l'inscription AppContext.LogManager.LogSysActivity($"Un client pour le profil {profile.Name} est déjà en cours d’exécution. " + "Inscription rejetée", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, data)); } AppContext.LogManager.LogSysActivity($"Désactivation du client {ClientStrID(oldClient.ID)}", true); //maj la table des status clients var oldClStatus = m_ndxerClientsStatus.Get(oldClient.ID) as ClientStatus; oldClStatus.Status = ClientStatus_t.Disabled; int ndx = m_ndxerClientsStatus.IndexOf(oldClStatus.ID); m_ndxerClientsStatus.Source.Replace(ndx, oldClStatus); //maj des fichiers de dialogue de old client string filePath = AppPaths.GetSrvDialogFilePath(oldClient.ID); ClientDialog clDlg = new ClientDialog(oldClient.ID, ClientStatus_t.Disabled, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(filePath, clDlg); AddUpload(Names.GetSrvDialogFile(oldClient.ID)); } //creer le fichier dialogue string srvDlgPath = AppPaths.GetSrvDialogFilePath(clInfo.ClientID); DialogEngin.WriteSrvDialog(srvDlgPath, new ClientDialog(clInfo.ClientID, ClientStatus_t.Enabled, Enumerable.Empty <Message>())); DialogEngin.WriteHubDialog(AppPaths.GetClientDilogFilePath(clInfo.ClientID), clInfo.ClientID, Enumerable.Empty <Message>()); try { new NetEngin(AppContext.Settings.NetworkSettings).Upload(Urls.DialogDirURL, new string[] { AppPaths.GetClientDilogFilePath(clInfo.ClientID), AppPaths.GetSrvDialogFilePath(clInfo.ClientID) }); } catch (Exception ex) { AppContext.LogManager.LogSysError($"Traitement de la requête d'inscription du client {ClientStrID(clInfo.ClientID)}: " + $"{ ex.Message}. demande ignorée, laisser le client reformuler la requête", true); return(null); // let the cleint retry req. } //maj la table des clients var hClient = new HubClient(clInfo.ClientID, clInfo.ProfileID) { ContaclEMail = clInfo.ContaclEMail, ContactName = clInfo.ContactName, ContactPhone = clInfo.ContactPhone, }; m_ndxerClients.Source.Insert(hClient); //maj du status client var clStatus = new ClientStatus(clInfo.ClientID, ClientStatus_t.Enabled); m_ndxerClientsStatus.Source.Insert(clStatus); //maj du client env UpdateClientEnvironment(clInfo.ClientID, clEnv); //maj du dict des clients actifs m_onlineClients.Add(clInfo.ClientID); AppContext.LogManager.StartLogger(clInfo.ClientID); AppContext.LogManager.LogClientActivity(clInfo.ClientID, "Inscription"); ClientStarted?.Invoke(clInfo.ClientID); AppContext.LogManager.LogSysActivity($"Inscription du client {clInfo.ClientID} terminée", true); TextLogger.Info("Inscription réussie. :-)"); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Ok, data)); }
Message ProcessResumeConnectionReq(Message msg) { Dbg.Assert(msg.MessageCode == Message_t.Resume); //verfier que le client existe uint clID = BitConverter.ToUInt32(msg.Data, 0); var client = m_ndxerClients.Get(clID) as HubClient; if (client == null) { AppContext.LogManager.LogSysActivity("Réception d’une requête de reprise émanant d’un client non enregistré. Réinitialisation du client.", true); //maj du fichier gov string srvDlgFile = AppPaths.GetSrvDialogFilePath(clID); //le client n'existe pas => son fichier gov n'existe pas var clDlg = new ClientDialog(clID, ClientStatus_t.Reseted, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(srvDlgFile, clDlg); AddUpload(Path.GetFileName(srvDlgFile)); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, BitConverter.GetBytes(clID))); } var prf = m_ndxerProfiles.Get(client.ProfileID) as UserProfile; AppContext.LogManager.LogSysActivity($"Requête de reprise émanant de {ClientStrID(clID)} pour le profil " + $"{prf.Name}, inscrit le {client.CreationTime}", true); //verifier que le profil est en mode auto if ((m_ndxerProfilesMgmnt.Get(prf.ID) as ProfileManagementMode).ManagementMode == ManagementMode_t.Manual) { AppContext.LogManager.LogSysActivity($"Le profil {prf.Name} est en gestion manuelle. Requête de reprise rejetée", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, msg.Data)); } //appliquer l'alog. de selction du client // si date inscription client actif <= date inscription client en pause // rejeter le demande //sinon // bannir le client actif // acvtiver le client en pause var curClient = GetProfileEnabledClient(prf.ID) as HubClient; if (curClient != null) { if (curClient.CreationTime <= client.CreationTime) { AppContext.LogManager.LogSysActivity($"Le client actif {ClientStrID(curClient.ID)} inscrit le " + $"{curClient.CreationTime}. Le client actif est plus ancien. Requête de reprise rejetée", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Rejected, msg.Data)); } //bannissemnt du client actif AppContext.LogManager.LogSysActivity($"Le client actif {ClientStrID(curClient.ID)} inscrit le " + $"{curClient.CreationTime}. Le client demandeur de reprise est plus ancien. Bannissement du client actif", true); //maj de la table des statuts var curClStatus = m_ndxerClientsStatus.Get(curClient.ID) as ClientStatus; curClStatus.Status = ClientStatus_t.Banned; int ndxCurClient = m_ndxerClientsStatus.IndexOf(curClStatus.ID); m_ndxerClientsStatus.Source.Replace(ndxCurClient, curClStatus); //maj du fichier distant g string curClFilePath = AppPaths.GetSrvDialogFilePath(curClient.ID); var curClDlg = new ClientDialog(curClient.ID, ClientStatus_t.Banned, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(curClFilePath, curClDlg); AddUpload(Names.GetSrvDialogFile(curClient.ID)); } //activation du client demandeur //reset dlg files DialogEngin.WriteHubDialog(AppPaths.GetClientDilogFilePath(clID), clID, Enumerable.Empty <Message>()); DialogEngin.WriteSrvDialog(AppPaths.GetSrvDialogFilePath(clID), new ClientDialog(clID, ClientStatus_t.Enabled, Enumerable.Empty <Message>())); try { new NetEngin(AppContext.Settings.NetworkSettings).Upload(Urls.DialogDirURL, new string[] { AppPaths.GetClientDilogFilePath(clID), AppPaths.GetSrvDialogFilePath(clID) }); } catch (Exception ex) { AppContext.LogManager.LogSysError($"Traitement de la requête de reprise du client {ClientStrID(clID)}: " + $"{ ex.Message}. demande ignorée, laisser le client reformuler la requête", true); return(null); // let the cleint retry req. } //maj de la table des statuts var clStatus = m_ndxerClientsStatus.Get(clID) as ClientStatus; clStatus.Status = ClientStatus_t.Enabled; int ndxClient = m_ndxerClientsStatus.IndexOf(clID); m_ndxerClientsStatus.Source.Replace(ndxClient, clStatus); //maj du dic des clients actifs m_onlineClients.Add(clID); AppContext.LogManager.StartLogger(clID); AppContext.LogManager.LogClientActivity(clID, "Reprise."); ClientStarted?.Invoke(clID); AppContext.LogManager.LogSysActivity($"Demande de reprise du client {ClientStrID(clID)} acceptée", true); return(msg.CreateResponse(++m_lastCnxRespMsgID, Message_t.Ok, msg.Data)); }