Aplikacja klient - serwer z użyciem puli wątków.

0

Witam. Chciałem przerobić swój stary projekt napisany w Javie SE. Aplikacja była typu klient - serwer na socketach. Wcześniej serwer wyglądał tak, że w pętli czekałem na podłączenie się klienta i tworzyłem dla niego osobny wątek, w którym obsługiwałem żądania od niego:

        while (run) {
            Socket clientSocket = serverSocket.accept();
            //utworzenie nowego wątku dla klienta i obsługa żadań od niego.
        }

Jednak z tego co się orientuję to rozwiązanie nie jest najlepsze, bo dla każdego klienta muszę tworzyć nowy wątek. Spróbowałem to przerobić na serwer z pulą wątków:

public void runServer() throws IOException {
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    try (BufferedReader bufferedReader = new BufferedReader(new FileReader("configuration\\server-settings.txt"))) {
        serverSocket = new ServerSocket(Integer.parseInt(bufferedReader.readLine()));
        while (run) {
            Socket clientSocket = serverSocket.accept();
            executorService.execute(new WorkerRunnable(clientSocket));
        }
    } finally {
        executorService.shutdown();
        closeServerSocket();
    }
}

Wtedy moja klasa WorkerRunnable implementuje następująco metodę run:

    public void run() {
    try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
         ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
        invokeActionStrategy(objectOutputStream, objectInputStream);
        socket.close();
    } catch (IOException ex) {
        LOGGER.error("Error while creating server", ex);
    }
}

We wcześniejsze wersji, gdzie utrzymywałem połączenie z klientem w powyższej metodzie była pętla nieskończona(też słabe rozwiązanie), która obsługiwała żądania klienta. Jakoś się to sprawdziło bo każdy klient miał swój wątek. Jednak kiedy posiadam pulę wątków, raczej nie powinienem trzymać połączenie z klientem, bo oznaczałoby to, że maksymalnie 10 klientów(bo tak mam przykładowo ustawione) byłoby w stanie komunikować się z serwerem.
Teraz mając pulę i nie utrzymując stałego połączenia z klientem za pomocą osobnego wątku, działa to na takiej zasadzie, że za każdym razem kiedy klient chce wysłać coś na serwer podłącza się do niego za pomocą:

Socket socket = new Socket(server, Integer.parseInt(port));

Serwer w pętli akceptuje połączenie, wykonuje operacje i odsyła dane i tak za każdym razem. Tutaj moja wątpliwość czy takie każdorazowe podłączanie się do serwera przez klienta nie jest niewydajne? We wcześniejszej wersji z osobnym wątkiem dla klienta, wystarczyło tylko jednorazowe wywołanie połączenia się z serwerem.

Jakie jest najlepsze rozwiązanie architektoniczne dla takiej aplikacji klient - serwer z pulą wątków?

0

poczytaj sobie o NIO lub zainteresuje się biblioteką Netty

0

Pytanie: po co Ci potrzebny jeden wątek na klienta?

Choć jeśli masz tak do kilkuset klientów równoczesnych to oczywiście będzie działać.

Sam wolę robić podobne rzeczy robić klasycznie na HTTP/websocket - ale bez wątków (np. Ratpackiem na wspomnianym wyżej netty).
(wtedy kilka wątkow starcza na tysiące klientów... ale za to programowanie czasem może być wyzwaniem).

Możesz tez zupełnie po staremu Tomcat i Websockety.

1 użytkowników online, w tym zalogowanych: 0, gości: 1