日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文介紹了如何將對象從inputStream客戶端返回到JavaFX控制器?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

所以基本上我有一個MainConstroll類,它有每個按鈕的方法。我還有一個服務器多客戶端應用程序。在客戶端,我有一個sendMessage方法,它將一個字符串和一個對象作為參數發送到outputStreams到服務器。

在相同的方法中,我有兩個來自服務器的消息的inputStream和一個對象。問題是此方法運行在實現Run方法的Thread上,而我無法返回該對象。

我嘗試創建一個靜態類來保存這些參數,但在控制器類中調用時,getter為空。

實現此目標的最佳方法是什么?

public void onSaveButton(javafx.event.ActionEvent actionEvent) throws Exception {


    Parent root = null;
    Boolean type = false;
    String message = null;


    if (adminCheckbox.isSelected()) {
        root = FXMLLoader.load(getClass().getResource("/fxml/admin.fxml"));
        type = true;
        message = "Admin";
    }

    if (competitorCheckbox.isSelected()) {
        root = FXMLLoader.load(getClass().getResource("/fxml/competitor.fxml"));
        message = "Competitor";
    }

    PersonEntity personEntity = new PersonEntity();
    personEntity.setIdTeam(Integer.parseInt(teamField.getText()));
    personEntity.setType(type);
    personEntity.setUsername(usernameField.getText());

    client.sendMessageToServer(message, personEntity);

    System.out.println(Utils.getMessage());}

和客戶端方法:

 public void sendMessageToServer(String message, Object object) throws Exception {

    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Say something and the message will be sent to the server: ");

            //For receiving and sending data
            boolean isClose = false;

            while (!isClose) {
                try {

                    ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
                    ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());

                    if (message.equals("Bye")) {
                        isClose = true;
                    }

                    outputStream.writeObject(message);
                    outputStream.writeObject(object);

                    String messageFromServer = (String) inputStream.readObject();
                    //System.out.println(messageFromServer);

                    int index = messageFromServer.indexOf(' ');
                    String word = messageFromServer.substring(0, index);

                    if (messageFromServer.equals("Bye")) {
                        isClose = true;
                    }

                    if (!word.equals("LIST")) {
                        Object obj = (Object) inputStream.readObject();
                        Utils.setMessage(messageFromServer);
                        return;
                        //Utils.setObject(obj);
                        //System.out.println("IN FOR " + Utils.getMessage());

                    } else {
                        List<Object> list = (List<Object>) inputStream.readObject();
                        Utils.setMessage(messageFromServer);
                        Utils.setObjects(list);
                        return;

                    }

                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

推薦答案

我不知道您的服務器是什么,也不知道您的應用程序的其余部分。我知道您正在使用原始的TCP套接字使用自定義協議進行通信。

我所做的是從Java教程中獲取類似示例的代碼。該代碼是來自Writing the Server Side of a Socket的Knock客戶端服務器代碼。基本的服務器代碼沒有改變,我只是用一個JavaFX用戶界面替換了基于控制臺的客戶端。

未更改的服務器代碼:

https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KnockKnockProtocol.java

https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KKMultiServer.java

https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KKMultiServerThread.java

已更換控制臺客戶端:

https://docs.oracle.com/javase/tutorial/networking/sockets/examples/KnockKnockClient.java

我提供了兩種不同的客戶端實現;一種是在JavaFX應用程序線程上進行同步客戶端調用,另一種是使用JavaFX任務進行異步客戶端調用。

當前的基于任務的異步解決方案對于一個完整規模的生產系統來說不夠健壯,因為它在技術上有可能丟失消息,并且它不能可靠地匹配請求和響應消息。但對于這樣的演示來說,這是可以的。

為了簡單執行,UI應用程序在運行時都會在預定義的端口上啟動本地服務器,但您可以刪除代碼以從UI應用程序啟動服務器,并在需要時從命令行運行服務器。

Knock Knock SyncClient.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class KnockKnockSyncClient {
    private Socket socket;
    private PrintWriter out;
    private BufferedReader in;

    public String connect(String host, int port) {
        try {
            socket = new Socket(host, port);

            out = new PrintWriter(
                    socket.getOutputStream(),
                    true
            );

            in = new BufferedReader(
                    new InputStreamReader(
                            socket.getInputStream()
                    )
            );

            return in.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public String sendMessage(String request) {
        String response = null;

        try {
            out.println(request);
            response = in.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return response;
    }

    public void disconnect() {
        try {
            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Knock Knock SyncApp

import javafx.animation.FadeTransition;
import javafx.application.*;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class KnockKnockSyncApp extends Application {
    private static final String HOST = "localhost";
    private static final int PORT = 8809;

    public static final String QUIT_RESPONSE = "Bye.";

    private ExecutorService serverExecutor;
    private KnockKnockSyncClient client;

    private static final String CSS = """
            data:text/css,
            .root {
                -fx-font-size: 20;
            }
            .list-cell {
                -fx-alignment: baseline-right;
                -fx-text-fill: purple;
            }
            .list-cell:odd {
                -fx-alignment: baseline-left;
                -fx-text-fill: darkgreen;
            }
            """;

    @Override
    public void init() {
        serverExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, "KKServer"));
        serverExecutor.submit(
                () -> {
                    try {
                        KKMultiServer.main(new String[]{ PORT + "" });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        );

        client = new KnockKnockSyncClient();
    }

    @Override
    public void start(Stage stage) {
        ListView<String> messageView = new ListView<>();

        TextField inputField = new TextField();
        inputField.setPromptText("Enter a message for the server.");

        inputField.setOnAction(event -> {
            String request = inputField.getText();
            messageView.getItems().add(request);

            String response = client.sendMessage(request);
            messageView.getItems().add(response);

            messageView.scrollTo(Math.max(0, messageView.getItems().size() - 1));

            inputField.clear();

            if (QUIT_RESPONSE.equals(response)) {
                closeApp(inputField.getScene());
            }
        });

        VBox layout = new VBox(10,
                messageView,
                inputField
        );
        layout.setPadding(new Insets(10));
        layout.setPrefWidth(600);

        Scene scene = new Scene(layout);
        scene.getStylesheets().add(CSS);

        stage.setScene(scene);
        stage.show();

        inputField.requestFocus();

        String connectResponse = client.connect(HOST, PORT);
        if (connectResponse != null) {
            messageView.getItems().add(connectResponse);
        }
    }

    private void closeApp(Scene scene) {
        Parent root = scene.getRoot();
        root.setDisable(true);
        FadeTransition fade = new FadeTransition(Duration.seconds(1), root);
        fade.setToValue(0);
        fade.setOnFinished(e -> Platform.exit());
        fade.play();
    }

    @Override
    public void stop() {
        client.disconnect();
        serverExecutor.shutdown();
    }

    public static void main(String[] args) {
        launch();
    }
}

Knock Knock AsyncClient.java

import javafx.concurrent.Task;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

public class KnockKnockAsyncClient extends Task<Void> {
    private final String host;
    private final int port;

    private final BlockingQueue<String> messageQueue = new LinkedBlockingDeque<>();

    public KnockKnockAsyncClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    protected Void call() {
        try (
                Socket kkSocket = new Socket(host, port);
                PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), true);
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(kkSocket.getInputStream()));
        ) {
            String fromServer;
            String fromUser;

            while ((fromServer = in.readLine()) != null) {
                // this is not a completely robust implementation because updateMessage
                // can coalesce responses and there is no matching in send message calls
                // to responses.  A more robust implementation may allow matching of
                // requests and responses, perhaps via a message id.  It could also
                // replace the updateMessage call with storage of results in a collection
                // (e.g. an observable list) with thread safe notifications of response
                // arrivals, e.g. through CompleteableFutures and/or Platform.runLater calls.
                updateMessage(fromServer);
                System.out.println("Server: " + fromServer);
                if (fromServer.equals("Bye."))
                    break;

                fromUser = messageQueue.take();
                System.out.println("Client: " + fromUser);
                out.println(fromUser);
            }
        } catch (InterruptedException e) {
            if (isCancelled()) {
                updateMessage("Cancelled");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    public void sendMessage(String request) {
        messageQueue.add(request);
    }
}

Knock Knock AsyncApp.java

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class KnockKnockAsyncApp extends Application {
    private static final String HOST = "localhost";
    private static final int PORT = 8809;

    public static final String QUIT_RESPONSE = "Bye.";

    private ExecutorService serverExecutor;
    private ExecutorService clientExecutor;

    private static final String CSS = """
            data:text/css,
            .root {
                -fx-font-size: 20;
            }
            .list-cell {
                -fx-alignment: baseline-right;
                -fx-text-fill: purple;
            }
            .list-cell:odd {
                -fx-alignment: baseline-left;
                -fx-text-fill: darkgreen;
            }
            """;

    @Override
    public void init() {
        serverExecutor = Executors.newSingleThreadExecutor(r -> new Thread(r, "KKServer"));
        serverExecutor.submit(
                () -> {
                    try {
                        KKMultiServer.main(new String[]{ PORT + "" });
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        );

        clientExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
            final AtomicInteger threadNum = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r,"KKClient-" + threadNum.getAndAdd(1));
            }
        });
    }

    @Override
    public void start(Stage stage) {
        ListView<String> messageView = new ListView<>();

        KnockKnockAsyncClient client = new KnockKnockAsyncClient(HOST, PORT);
        // monitor and action responses from the server.
        client.messageProperty().addListener((observable, oldValue, response) -> {
            if (response != null) {
                logMessage(messageView, response);
            }

            if (QUIT_RESPONSE.equals(response)) {
                closeApp(messageView.getScene());
            }
        });

        TextField inputField = new TextField();
        inputField.setPromptText("Enter a message for the server.");

        inputField.setOnAction(event -> {
            String request = inputField.getText();
            logMessage(messageView, request);

            client.sendMessage(request);

            inputField.clear();
        });

        VBox layout = new VBox(10,
                messageView,
                inputField
        );
        layout.setPadding(new Insets(10));
        layout.setPrefWidth(600);

        Scene scene = new Scene(layout);
        scene.getStylesheets().add(CSS);

        stage.setScene(scene);
        stage.show();

        inputField.requestFocus();

        clientExecutor.submit(client);
    }

    private void logMessage(ListView<String> messageView, String request) {
        messageView.getItems().add(request);
        messageView.scrollTo(Math.max(0, messageView.getItems().size() - 1));
    }

    private void closeApp(Scene scene) {
        Parent root = scene.getRoot();
        root.setDisable(true);
        FadeTransition fade = new FadeTransition(Duration.seconds(1), root);
        fade.setToValue(0);
        fade.setOnFinished(e -> Platform.exit());
        fade.play();
    }

    @Override
    public void stop() {
        clientExecutor.shutdown();
        serverExecutor.shutdown();
    }

    public static void main(String[] args) {
        launch();
    }
}

這篇關于如何將對象從inputStream客戶端返回到JavaFX控制器?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,

分享到:
標簽:InputStream JavaFX 如何將 客戶端 對象 控制器 返回
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定