Многопоточный сервер Java - каждое соединение возвращает данные. Обработка в главном потоке? - PullRequest
1 голос
/ 22 декабря 2010

Я пишу клиент со встроенным сервером, который должен бесконечно ждать новых подключений и обрабатывать каждое из них в потоке.

Я хочу обработать полученный массив байтов в общесистемном доступном обработчике сообщений в основной теме .Тем не менее, в настоящее время обработка, очевидно, выполняется в клиентском потоке.

Я смотрел на Futures, submit () из ExecutorService, но когда я создаю клиентские подключения на сервере, данные будут возвращеныСерверный поток.Как я могу вернуть его оттуда в основной поток (возможно, в синхронизированном хранилище пакетов), чтобы обработать его, не блокируя сервер?

Моя текущая реализация выглядит так:

    public class Server extends Thread {
    private int port;
    private ExecutorService threadPool;

    public Server(int port) {
        this.port = port;
        // 50 simultaneous connections
        threadPool = Executors.newFixedThreadPool(50);
    }

    public void run() {
        try{
            ServerSocket listener = new ServerSocket(this.port);
            System.out.println("Listening on Port " + this.port);
            Socket connection;

            while(true){
                try {
                    connection = listener.accept();
                    System.out.println("Accepted client " + connection.getInetAddress());
                    connection.setSoTimeout(4000);

                    ClientHandler conn_c= new ClientHandler(connection);
                    threadPool.execute(conn_c);
                } catch (IOException e) {
                    System.out.println("IOException on connection: " + e);
                }
            }
        } catch (IOException e) {
            System.out.println("IOException on socket listen: " + e);
            e.printStackTrace();
            threadPool.shutdown();
        }
    }
}
class ClientHandler implements Runnable {
    private Socket connection;

    ClientHandler(Socket connection) {
        this.connection=connection;
    }

    @Override
    public void run() {
        try {
            // Read data from the InputStream, buffered
            int count;
            byte[] buffer = new byte[8192];

            InputStream is = connection.getInputStream();
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            // While there is data in the stream, read it
            while ((count = is.read(buffer)) > 0) {
                out.write(buffer, 0, count);
            }
            is.close();
            out.close();

            System.out.println("Disconnect client " + connection.getInetAddress());
            connection.close();
            // handle the received data
            MessageHandler.handle(out.toByteArray());
        } catch (IOException e) {
            System.out.println("IOException on socket read: " + e);
            e.printStackTrace();
        }
        return;

    }
}

Обновление: Кажется, что TomTom предлагает более надежный способ - использовать более новый java.nio.Поскольку этот проект имеет ограниченное использование и является скорее экспериментом, я хотел бы узнать, как лучше всего использовать его с java.io/java.net:)

Ответы [ 2 ]

0 голосов
/ 23 декабря 2010

В моем варианте вы можете использовать объект синхронизации для чата с основным потоком, после добавления клиентских подключений к пулу основной поток может заблокировать на приеме и объект синхронизации, после того, как клиент обработает его, поместитеобработал сокет соединения и ответ на очередь, а затем активировал объект синхронизации, чтобы основной поток мог затем получить что-то из очереди и обработать его, после того как основной поток обработает его, заблокировать при принятии и ждать в объекте синхронизации.

По сути, ваша архитектура является простым / прямым способом, новый способ - использовать java nio, чтобы получить больше серверов параллелизма и повысить производительность, также nio - не лучший способ ...

0 голосов
/ 22 декабря 2010

Это не масштаб.По какой причине ты это делаешь?Кроме того, вы тратите тонны памяти - вам не нужна нить в розетку.Используйте лучшую библиотеку Java IO.Как тот, который доступен как часть Java в течение примерно 10 лет (NGIO?).Он обрабатывает x потоков с одним сокетом, просто возвращая данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...