«Клієнт-сервер» це дуже поширена і логічна архітектура додатків. Мені здається, що в наші дні рідко можна зустріти standalone-клієнтську програму. Тому я прийняв рішення розглянути приклад побудови клієнт-серверного додатка на Java без прив'язки до конкретного завдання. Спочатку коротко пробіжимося по класовій структурі додатки, потім подивимося на окрему реалізацію кожного класу. В самому кінці статті я дам посилання на скачування архіву з готовою структурою програми. Тож почнемо.
Основні компоненти програми
Основними компонентами, природно, є безпосередньо клієнт і сервер. Однак, крім них необхідний ще пакет допоміжних класів, які, в найпростішому випадку, будуть відповідати за обмін повідомленнями між клієнтом і сервером. У мінімальній комплектації потрібні такі класи: MessageReader / MessageWriter (зчитує / записує повідомлення в потік на сокеті), MessageFactory (містить ідентифікатори всіх можливих повідомлень), набір повідомлень-запитів (Request) і набір повідомлень-відповідей (Response). Всі вони будуть розміщені в пакеті «core», який повинні мати у себе і клієнт і сервер.
Розглянемо класову структуру всього проекту, а потім перейдемо до реалізації.
Класова структура клієнт-серверного додатка
Вихідний код клієнта на Java
Розібратися з клієнтом набагато простіше, він по суті своїй не робить нічого супер складного, просто створює сокет і підключається до сервер-сокету за допомогою зв'язки host: port. Лаунчер створює об'єкт класу Client і запускає його роботу. Вихідний код привожу без імпорту, бо будь-яка IDE вам їх підключить (ті, хто пише на Java точно знають, що без IDE дуже складно). Крім того, в кінці статті ви зможете скачати архів з цим проектом.
ClientLauncher.java
Client.java
Під словами «логіка додатки» я маю на увазі протокол обміну повідомленнями з сервером, передачу будь-яких даних для досягнення кінцевої мети.
Вихідний код сервера на Java
Нагадаю, що в класі ClientSession описаний основний алгоритм роботи з клієнтом, обмін повідомленнями, даними та інше. У класі Context міститься загальна інформація для всіх клієнтів сервера, наприклад, шляхи для збереження логів.
ServerLauncher.java
Server.java
Context.java
ClientSession.java
SessionsManager.java
Допоміжні класи з пакета «core»
Поміщу всі допоміжні класи під один кат, назва класів в точності відповідає назвам зі списку «класова структура» вище, по ньому ви можете визначити пакет кожного класу.
Пара слів про повідомлення, класи Request і Response є абстрактними і грають роль класифікаторів повідомлення. Завдяки цьому дуже зручно розмежовувати «запити» від «відповідей». У цьому прикладі я привів тільки одне повідомлення - Handshake. яке відповідає за перше «рукостискання» клієнта і сервера. Усі наступні повідомлення повинні бути прописані в класі MessageFactory за прикладом цих двох.