Диалог с Сервером со стороны Kлиента

113
11 августа 2019, 18:50

Нужно чтобы клиент постоянно находился в режиме ожидания ввода команд со стороны пользователя. Эти команды затем отправляются на сервер.

Нашел много примеров Клиент-Серверного общения (Java).
Например этот: Простейшее клиент-серверное приложение

В этом примере клиент ожидает ввода с консоли. А как сделать ожидание ввода с компонета управления, например TextField (JavaFX)?

Есть идея, сохранять текст из TextField в некую переменную. Клиент будет раз в секунду проверять эту переменную на изменения. При изменении отправлять строку на сервер.

Либо обработать событие ActionEvent для TextField . Можно ли определить в клиенте функцию, которая будет получать строку и отправлять ее на сервер? Эта функция я полагаю должна вызываться из обработчика ActionEvent .

Класс клиент выполняется в отдельном потоке относительно главного приложения, чтобы не повесить интерфейс пользователя. Есть ли способ поставить клиент в режим ожидания и включать его, только если нужно отправить сообщение на сервер ?

Answer 1

Можно организовать приостановление и возобновления потока клиент с помощью функций wait(), notify() . Вот минимальная рабочая часть кода класса клиент:

public class MyClient extends Thread{
    private DataOutputStream ostream ;
    private DataInputStream istream;
    private Socket socket;
    private boolean isPause;
    private boolean isContinue;
    private String command;
    private final String HOST;
    private final int PORT;
    private final int BUFF_SIZE=64;
    private final GuiElement guiElement;
    public MyClient(String HOST, int PORT,GuiElement guiElement) {
        this.HOST=HOST;
        this.PORT=PORT;
        this.guiElement=guiElement;
        this.isPause=true;
        this.isContinue=true;
        this.setDaemon(true);
        try {
            socket = new Socket(HOST, PORT);
            ostream = new DataOutputStream(socket.getOutputStream());
            istream = new DataInputStream(socket.getInputStream());
        } catch (Exception e) {
            isPause=false;
            isContinue=false;
        }
        start();
    }
    public void run() {
        while(isContinue) {
            //-----waiting
            synchronized(this) {
                while(isPause) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        closeSocket();
                    }
                }
            }
            //-----sending command
            sendCommand();
        }
        closeSocket();
    }
    //-----invoked from the class that creates this Client thread
    //-----when the user has clicked the enter button on the input field 
    synchronized public void setCommand(String command) {
        this.command=command;
        isPause=false;
        notify();
    }
    private void sendCommand() {
        try {
            ostream.write(command.getBytes());
            ostream.flush();
            byte buf[] = new byte[BUFF_SIZE];
            int r;
            r = istream.read(buf);
            String data = new String(buf, 0, r);
        } catch (Exception e) {
            closeSocket();
        }
        Platform.runLater(() -> guiElement.print(data)); /* display a message on a GUI element  */
        isPause=true;
    }
    private void closeSocket() {
        try {
            if(socket.isClosed())return;
            else socket.close();
        } catch (Exception e) {
            isPause=false;
            isContinue=false;
        }
    }
}

После запуска поток клиент находится в режиме ожидания. При вызове извне (из основного потока, который обращается к потоку клиент например так: client.setCommand(some message) ) функции setCommand() устанавливается текущая команда и уведомляется о прекращении ожидания ( notify() ) . Далее поток выходит из блока while(isPause){...} для отправки команды серверу самостоятельно запуская функцию sendCommand(). После выполнения функции sendCommand() поток снова переходит в режим ожидания попадая в блок while(isPause){...}

READ ALSO
Не отскакивает тело box2d

Не отскакивает тело box2d

При столкновении с другим телом ball либо останавливается, либо двигается вдоль негоВроде как это может происходить из-за неправильного world scale,...

122
Создание файла MS Word при нажатии на кнопку в графическом интерфейсе

Создание файла MS Word при нажатии на кнопку в графическом интерфейсе

Пытаюсь получить строковую переменную из "TextField" и передать ее в создаваемый файл MS Word

122
Не могу получить данные из базы данных

Не могу получить данные из базы данных

Пробую делать мини приложение, что-то типа доски объявленийНи как не получается у меня сделать поиск по фильтру

121
Как поместить объекты enum в коллекцию?

Как поместить объекты enum в коллекцию?

Есть объекты enum, надо их поместить в коллекциюКак это сделать?

122