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

Aplikacja klient - serwer z użyciem puli wątków.
O1
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 5 godzin
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:

Kopiuj
        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:

Kopiuj
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:

Kopiuj
    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ą:

Kopiuj
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?

MO
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 10 godzin
0

poczytaj sobie o NIO lub zainteresuje się biblioteką Netty

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
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.


jeden i pół terabajta powinno wystarczyć każdemu
S9
@jarekr000000: dobrze że jesteś, brakowało mi CIebie :) W końcu będzie znowu można pogadac o kontenerach IoC :D

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.