Чат на Java (Серверная часть)

Чат на Java (Серверная часть)

Всем доброго времени суток. На связи Алексей Гулынин. В данной статье я бы хотел написать серверную часть простого чата на Java. Все комментарии будут даны в коде.

Скачать уже готовый проект полностью можно по ссылке.

Проект серверной части будет состоять из 3 файлов:

  • Server.java — класс, который описывает логику работы сервера.
  • ClientHandler.java — класс, в котором обрабатывается подключение клиента к серверу.
  • Main.java.

В классе Main будет просто создаваться экземпляр нашего сервера:

package server;

public class Main {

  public static void main(String[] args) {
    Server server = new Server();
  }
}

Класс Server:

package server;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class Server {
  // порт, который будет прослушивать наш сервер
  static final int PORT = 3443;
  // список клиентов, которые будут подключаться к серверу
  private ArrayList<ClientHandler> clients = new ArrayList<ClientHandler>();

  public Server() {
    // сокет клиента, это некий поток, который будет подключаться к серверу
    // по адресу и порту
    Socket clientSocket = null;
    // серверный сокет
    ServerSocket serverSocket = null;
    try {
      // создаём серверный сокет на определенном порту
      serverSocket = new ServerSocket(PORT);
      System.out.println("Сервер запущен!");
      // запускаем бесконечный цикл
      while (true) {
        // таким образом ждём подключений от сервера
        clientSocket = serverSocket.accept();
        // создаём обработчик клиента, который подключился к серверу
        // this - это наш сервер
        ClientHandler client = new ClientHandler(clientSocket, this);
        clients.add(client);
        // каждое подключение клиента обрабатываем в новом потоке
        new Thread(client).start();
      }
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }
    finally {
      try {
        // закрываем подключение
        clientSocket.close();
        System.out.println("Сервер остановлен");
        serverSocket.close();
      }
      catch (IOException ex) {
        ex.printStackTrace();
      }
    }
  }
		
  // отправляем сообщение всем клиентам
  public void sendMessageToAllClients(String msg) {
    for (ClientHandler o : clients) {
      o.sendMsg(msg);
    }

  }

  // удаляем клиента из коллекции при выходе из чата
  public void removeClient(ClientHandler client) {
    clients.remove(client);
  }

}

Класс ClientHandler:

package server;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;

// реализуем интерфейс Runnable, который позволяет работать с потоками
public class ClientHandler implements Runnable {
  // экземпляр нашего сервера
  private Server server;
  // исходящее сообщение
  private PrintWriter outMessage;
  // входящее собщение
  private Scanner inMessage;
  private static final String HOST = "localhost";
  private static final int PORT = 3443;
  // клиентский сокет
  private Socket clientSocket = null;
  // количество клиента в чате, статичное поле
  private static int clients_count = 0;

  // конструктор, который принимает клиентский сокет и сервер
  public ClientHandler(Socket socket, Server server) {
    try {
      clients_count++;
      this.server = server;
      this.clientSocket = socket;
      this.outMessage = new PrintWriter(socket.getOutputStream());
      this.inMessage = new Scanner(socket.getInputStream());
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }
  // Переопределяем метод run(), который вызывается когда
  // мы вызываем new Thread(client).start();
  @Override
  public void run() {
    try {
      while (true) {
        // сервер отправляет сообщение
        server.sendMessageToAllClients("Новый участник вошёл в чат!");
        server.sendMessageToAllClients("Клиентов в чате = " + clients_count);
        break;
      }

      while (true) {
        // Если от клиента пришло сообщение
        if (inMessage.hasNext()) {
        String clientMessage = inMessage.nextLine();
	// если клиент отправляет данное сообщение, то цикл прерывается и 
	// клиент выходит из чата
        if (clientMessage.equalsIgnoreCase("##session##end##")) {
          break;
        }
	// выводим в консоль сообщение (для теста)
        System.out.println(clientMessage);
	// отправляем данное сообщение всем клиентам
        server.sendMessageToAllClients(clientMessage);
      }
      // останавливаем выполнение потока на 100 мс
      Thread.sleep(100);
    }
  }
  catch (InterruptedException ex) {
    ex.printStackTrace();
  }
  finally {
    this.close();
  }
}
  // отправляем сообщение
  public void sendMsg(String msg) {
    try {
      outMessage.println(msg);
      outMessage.flush();
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  // клиент выходит из чата
  public void close() {
    // удаляем клиента из списка
    server.removeClient(this);
    clients_count--;
    server.sendMessageToAllClients("Клиентов в чате = " + clients_count);
  }
}

В данной статье мы создали серверную часть простого чата на Java.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *