/// <summary> /// Добавление клиента в системы сервера /// </summary> /// <param name="client">Клиент</param> private void AddClientServer(ClientSDB client) { if (!WorkClientGroup.ClientAvailability(client.Address) && !WorkMySQL.ClientAvailability(client.Address)) { ClientServerDB clientServer = new ClientServerDB(client); WorkClientGroup.AddClient(clientServer); WorkMongo.AddClient(clientServer); try { WorkMySQL.AddClient(clientServer); WorkRabbit.RedistributionQueue(WorkRabbit.QueueUnallocated, WorkRabbit.ExchangeBook, WorkRabbit.RoutingBook); } catch (MySqlException) { WorkMongo.DeleteClient(clientServer.Address); StopServer(); } catch (RabbitmqException) { WorkMongo.DeleteClient(clientServer.Address); WorkMySQL.FullDeleteClient(clientServer.Address); StopServer(); } } }
/// <summary> /// Разгрузка очередей перегруженных клиентов /// </summary> /// <param name="client">Потенциальный клиент на разгруженные книги</param> private void UnloadingQueuesClientsServer(ClientSDB client) { if (!WorkClientGroup.ClientsAvailability()) { return; } Dictionary <string, Queue <string> > unloadingBooksQueues = WorkClientGroup.UnloadingQueuesClients(client, AlignmentCoefficient); foreach (var dictionaryBookQueue in unloadingBooksQueues) { int countBook = dictionaryBookQueue.Value.Count; for (int i = 0; i < countBook; i++) { WorkMongo.DeletionBookFromQueue(dictionaryBookQueue.Key); string book = dictionaryBookQueue.Value.Peek(); try { WorkRabbit.PublishBookQueue(book); } catch (RabbitmqException) { WorkMongo.AddBookInQueue(dictionaryBookQueue.Key, book); StopServer(); } dictionaryBookQueue.Value.Dequeue(); } WorkClientGroup.SetRecalculateTimeRead(dictionaryBookQueue.Key); WorkClientGroup.SetReleaseMutexJointOperation(dictionaryBookQueue.Key); } }
/// <summary> /// Разгрузка очередей перегруженных клиентов /// </summary> /// <param name="client">Потенциальный клиент на разгруженные книги</param> /// <param name="alignmentCoefficient">Коэффициент выравнивания загружености клиентов</param> /// <returns>Очередь разгруженых книг</returns> public Dictionary <string, Queue <string> > UnloadingQueuesClients(ClientSDB client, double alignmentCoefficient) { Dictionary <string, Queue <string> > unloadingBooksQueue = new Dictionary <string, Queue <string> >(); DateTime reloadTimeRead = СalculationСriticalTimeRead(alignmentCoefficient); var selectedClient = from clientServer in ClientDictionary from lelaClientServer in clientServer.Value.GetClientServerDB().LevelLanguages from lelaClient in client.LevelLanguages where lelaClientServer.Language == lelaClient.Language && clientServer.Value.GetClientServerDB().TimeRead > reloadTimeRead select clientServer.Value; foreach (var selectImitationActivity in selectedClient) { selectImitationActivity.SetWaitOneMutexJointOperation(); ClientServerDB selectClientServer = selectImitationActivity.GetClientServerDB(); unloadingBooksQueue.Add(selectClientServer.Address, new Queue <string>()); while (selectClientServer.TimeRead > reloadTimeRead) { if (selectClientServer.QueueBook.Count > 0) { string book = selectClientServer.QueueBook.Dequeue(); unloadingBooksQueue[selectClientServer.Address].Enqueue(book); SetRecalculateTimeRead(selectClientServer.Address); } } } return(unloadingBooksQueue); }
/// <summary> /// Конструктор объекта клиента сервера /// </summary> /// <param name="clientSDB">Объект клиента </param> public ClientServerDB(ClientSDB clientSDB) { Surname = clientSDB.Surname; Name = clientSDB.Name; Address = clientSDB.Address; PagesPerDay = clientSDB.PagesPerDay; ReadingIntervalActive = clientSDB.ReadingIntervalActive; ReadingIntervalPassive = clientSDB.ReadingIntervalPassive; LevelLanguages = clientSDB.LevelLanguages; DataRegistration = clientSDB.DataRegistration; QueueBook = new Queue <string>(); TimeReadActive = DateTime.Now; TimeRead = DateTime.Now; }
/// <summary> /// Конструктор рссширеного объекта клиента /// </summary> /// <param name="clientSDB">Объект клиента </param> /// <param name="conn">Соединение с RabbitMQ</param> /// <param name="collection">Коллекция MongoDB</param> /// <param name="connectionString">Строка подключения MySQL</param> public ClientServerDB(ClientSDB clientSDB, IConnection conn, IMongoCollection <ClientServerDB> collection, string connectionString) { Surname = clientSDB.Surname; Name = clientSDB.Name; Address = clientSDB.Address; PagesPerDay = clientSDB.PagesPerDay; ReadingIntervalActive = clientSDB.ReadingIntervalActive; ReadingIntervalPassive = clientSDB.ReadingIntervalPassive; LevelLanguages = clientSDB.LevelLanguages; DataRegistration = clientSDB.DataRegistration; queueBook = new Queue <string>(); TimeReadActive = DateTime.Now; TimeRead = DateTime.Now; ReloadObject = false; InitComponent(conn, collection, connectionString); RedistributionUnallocatedBook(); }
/// <summary> /// Обработки данных клиента из RabbitMQ без обработки общих исключений /// </summary> /// <param name="sender">Вызывающий объект</param> /// <param name="e">Сообщение из RabbitMQ</param> private void TryAddDeleteClientRequest(object sender, BasicDeliverEventArgs e) { MutexOnlyMethod.WaitOne(); string bodyType = e.BasicProperties.Type; if (bodyType == WorkRabbit.PropetyAdding) { ClientSDB client = WorkRabbit.ConvertMessageRabbit <ClientSDB>(e.Body); UnloadingQueuesClientsServer(client); AddClientServer(client); WorkClientGroup.StartImitationActivityClient(client.Address); } else if (bodyType == WorkRabbit.PropetyDeleted) { string address = WorkRabbit.ConvertMessageRabbit <string>(e.Body); WorkClientGroup.StopImitationActivityClient(address); DeleteClientServer(address); } WorkRabbit.BasicAckRabbit(sender, e); MutexOnlyMethod.ReleaseMutex(); }
/// <summary> /// Добавление, удаление клиентов /// </summary> /// <param name="e">Объект сообщения</param> /// <param name="channel">Канал связи с RabbitMQ</param> /// <param name="conn">Соединение с RabbitMQ</param> /// <param name="collection">Коллекция MongoDB</param> /// <param name="connectionString">Строка подключения MySQL</param> private static void AddingDeletedClient(BasicDeliverEventArgs e, IModel channel, IConnection conn, IMongoCollection <ClientServerDB> collection, string connectionString) { mutexDAD.WaitOne(); //получение и распределение операций (добавление или отписка клиента) var body = e.Body; var bodytype = e.BasicProperties.Type; var message = Encoding.UTF8.GetString(body); //если добавление клиента if (bodytype == "Adding") { //сериализация клиента ClientSDB clientSDB = JsonSerializer.Deserialize <ClientSDB>(message); //проверка клиента на наличие в базе if (!listClient.ContainsKey(clientSDB.Address)) { //проверка в MySQL был ли клиент раннее подписан string sqlcommand = "SELECT Address FROM clients WHERE Address = @Address"; bool HasRows; using (MySqlConnection connMySQL = new MySqlConnection(connectionString)) { connMySQL.Open(); MySqlCommand commandchek = new MySqlCommand(sqlcommand, connMySQL); MySqlParameter AddressCheckParam = new MySqlParameter("@Address", clientSDB.Address); commandchek.Parameters.Add(AddressCheckParam); MySqlDataReader reader = commandchek.ExecuteReader(); HasRows = reader.HasRows; } if (!HasRows) { //создание рассширеного объекта клиента и добавление его в список ClientServerDB clientServerDB = new ClientServerDB(clientSDB, conn, collection, connectionString); listClient.Add(clientServerDB.Address, clientServerDB); //добавление клиента в MongoDB ClientServerDB clientServerDBMongo = clientServerDB.ConvertMongoDate(); collection.InsertOne(clientServerDBMongo); //добавление клиента в MySQL using (MySqlConnection connMySQL = new MySqlConnection(connectionString)) { connMySQL.Open(); MySqlCommand command = new MySqlCommand(); command.Connection = connMySQL; command.CommandText = "INSERT INTO clients (Address, Surname, Name, PagesPerDay, ReadingIntervalActive, " + "ReadingIntervalPassive, DataRegistration, Subscription) " + "VALUES (@Addres, @Surname, @Name, @PagesPerDay, @ReadingIntervalActive, @ReadingIntervalPassive, @DataRegistration, @Subscription)"; MySqlParameter AddressParam = new MySqlParameter("@Addres", clientServerDB.Address); command.Parameters.Add(AddressParam); MySqlParameter SurnameParam = new MySqlParameter("@Surname", clientServerDB.Surname); command.Parameters.Add(SurnameParam); MySqlParameter NameParam = new MySqlParameter("@Name", clientServerDB.Name); command.Parameters.Add(NameParam); MySqlParameter PagesPerDayParam = new MySqlParameter("@PagesPerDay", clientServerDB.PagesPerDay); command.Parameters.Add(PagesPerDayParam); MySqlParameter ReadingIntervalActiveParam = new MySqlParameter("@ReadingIntervalActive", clientServerDB.ReadingIntervalActive); command.Parameters.Add(ReadingIntervalActiveParam); MySqlParameter ReadingIntervalPassiveParam = new MySqlParameter("@ReadingIntervalPassive", clientServerDB.ReadingIntervalPassive); command.Parameters.Add(ReadingIntervalPassiveParam); MySqlParameter DataRegistrationParam = new MySqlParameter("@DataRegistration", clientServerDB.DataRegistration); command.Parameters.Add(DataRegistrationParam); MySqlParameter SubscriptionParam = new MySqlParameter("@Subscription", "Подписан"); command.Parameters.Add(SubscriptionParam); command.ExecuteNonQuery(); foreach (LevelLanguageSDB ll in clientServerDB.LevelLanguages) { MySqlCommand commandll = new MySqlCommand(); commandll.Connection = connMySQL; commandll.CommandText = "INSERT INTO levellanguages (AddressClient, Language, Level) VALUES (@AddressClient, @Language, @Level)"; MySqlParameter AddressClientParam = new MySqlParameter("@AddressClient", clientServerDB.Address); commandll.Parameters.Add(AddressClientParam); MySqlParameter LanguageParam = new MySqlParameter("@Language", (int)ll.Language); commandll.Parameters.Add(LanguageParam); MySqlParameter LevelParam = new MySqlParameter("@Level", ll.Level); commandll.Parameters.Add(LevelParam); commandll.ExecuteNonQuery(); } } } } } //если отписка клиента else if (bodytype == "Deleted") { //проверка клиента на наличие в базе if (listClient.ContainsKey(message)) { //отписка клиента и удаление его из списка listClient[message].Unsubscribe(); listClient.Remove(message); //удаление клиента из MongoDB collection.DeleteOne(p => p.Address == message); //изменение статуса клиента на "Отписан" в MySQL using (MySqlConnection connMySQL = new MySqlConnection(connectionString)) { connMySQL.Open(); MySqlCommand command = new MySqlCommand(); command.Connection = connMySQL; command.CommandText = "UPDATE clients SET Subscription = 'Отписан' WHERE Address = @Address"; MySqlParameter AddressParam = new MySqlParameter("@Address", message); command.Parameters.Add(AddressParam); command.ExecuteNonQuery(); } } } channel.BasicAck(e.DeliveryTag, false); mutexDAD.ReleaseMutex(); }