IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

19. diel - Java chat - Klient - Spojenie so serverom 3. časť

V minulej lekcii, Java chat - Klient - Spojenie so serverom 2. časť , sme sa venovali implementácii klientského komunikátora. V dnešnom Java tutoriálu konečne vytvoríme stabilné spojenie so serverom.

Upravenie pripojovacieho kontroleru

Začneme upravením triedy ConnectController. V triede vytvoríme novú inštančný premennú typu IClientCommunicationService. Rovno tejto premennej vytvoríme setter, aby sme mohli komunikátor nastaviť:

public void setCommunicator(IClientCommunicationService communicator) {
    this.communicator = communicator;
    final BooleanBinding connected = Bindings.createBooleanBinding(() -> this.communicator.getConnectionState() == ConnectionState.CONNECTED, this.communicator.connectionStateProperty());
    btnConnect.disableProperty().bind(connected.or(txtServer.textProperty().isEmpty()));
    btnDisconnect.disableProperty().bind(connected.not());
    lblConnectedTo.textProperty().bind(this.communicator.connectedServerNameProperty());
}

Komunikátor musíme takto nastavovať, pretože nemáme v projekte implementovanú žiadnu správu závislostí, ako tomu bolo u servera. Ďalej v Setter vytvárame BooleanProperty connected, na ktorú bindujeme disableProperty tlačidiel pre pripojenie a odpojenie. DisableProperty tlačidla "pripojiť" má trošku zložitejšie logiku, pretože sa musíme ešte pozerať, či ak sa máme na čo pripojiť (je vyplnený TextField so serverom).

Ďalej upravíme metódu initialize(), do ktorej pridáme reakciu na výber položky z listView:

lvServers.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue == null) {
        return;
    }

    txtServer.textProperty().set(String.format("%s:%d", newValue.getServerAddress().getHostAddress(), newValue.getPort()));
});

Volaním metód getSelectionModel().selectedItemProperty() získame pozorovateľnú read-only property, na ktorú pridáme listener, ktorý sa zavolá vždy, keď zmeníme výber položky v listView. Pokiaľ bude nová hodnota null, tak nič robiť nebudeme, v opačnom prípade vyplníme TextField txtServer hodnotou vo formáte: "server: port".

Teraz vytvoríme najdôležitejšie metódu v kontroleru, connect(), pomocou ktorej sa budeme pripájať na server:

private void connect() {
    final String hostPort = txtServer.textProperty().get();
    final String host = hostPort.substring(0, hostPort.indexOf(":"));
    final String portRaw = hostPort.substring(hostPort.indexOf(":") + 1);
    int port;
    try {
        port = Integer.parseInt(portRaw);
    } catch (Exception ex) {
        Alert alert = new Alert(AlertType.ERROR);
        alert.setHeaderText("Chyba");
        alert.setContentText("Port serveru se nezdařilo naparsovat.");
        alert.showAndWait();
        return;
    }

    this.communicator.connect(host, port)
    .exceptionally(throwable -> {
        Alert alert = new Alert(AlertType.ERROR);
        alert.setHeaderText("Chyba");
        alert.setContentText("Připojení k serveru se nezdařilo.");
        alert.showAndWait();

        throw new RuntimeException(throwable);
    })
   .thenAccept(ignored -> {
       Alert alert = new Alert(AlertType.INFORMATION);
       alert.setHeaderText("Informace");
       alert.setContentText("Spojení bylo úspěšně navázáno.");
       alert.showAndWait();
   });
}

V prvej časti metódy dekóduje z TextField u adresu servera a port, na ktorom server počúva. Ak sa nepodarí naparsovat port servera, zobrazíme upozornenie užívateľovi, že port nie je vo validným stave. Nasleduje zavolanie metódy connect() nad inštancií nášho komunikátora. Metódou exceptionaly() ošetríme prípad, keď sa spojenie nepodarilo nadviazať. Keď sa raz dostaneme do vetvy exceptionaly(), môžeme v nej zostať tak, že opäť vyhodíme nejakú výnimku, alebo vrátime zmysluplnú hodnotu, čím sa dostaneme do východiskovej vetvy. Vetva thenAccept() je zavolaná v prípade, že spojenie sa úspešne vytvorilo.

Nakoniec nám už len zostáva nastaviť zodpovedajúcim tlačidlám správnu akciu:

@FXML
private void handleConnect(ActionEvent actionEvent) {
    connect();
}

@FXML
private void handleDisconnect(ActionEvent actionEvent) {
    communicator.disconnect();
}

Upravenie hlavného kontroleru

Teraz sa presunieme do hlavného kontroleru, v ktorom budeme držať jedinú inštanciu komunikátora. Vytvoríme teda v triede MainController inštančný konštantu komunikátora:

private final IClientCommunicationService communicator = new ClientCommunicationService();

Ďalej upravíme metódu handleConnect(), v ktorej voláme zobrazenia okna:

@FXML
private void handleConnect(ActionEvent actionEvent) {
    try {
        final ConnectController controller = showNewWindow("connect/connect", "Připojit k serveru...");
        controller.setCommunicator(communicator);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Metóda showNewWindow() vracia kontrolér nového okna. Tento kontrolér si uložíme do lokálnej premennej a metódou setCommunicator() nastavíme kontroleru komunikátor.

Ešte využijeme metódu onClose(), ktorá sa zavolá pri zatvorení okna. V tejto metóde sa pre istotu odpojíme od servera. Tým bezpečne ukončíme spojenie a všetka vlákna s ním spojená:

@Override
public void onClose() {
    communicator.disconnect()
}

Testovanie funkčnosti

Konečne sa môžeme pripojiť k serveru. Z predchádzajúcej lekcie máme funkčné vyhľadávanie lokálnych serverov, tak toho hneď využijeme. Spustíme server a klienta. Ďalej zobrazíme okno pre pripojenie. Keď sa zobrazí v zozname náš spustený server, klikneme na túto položku. V tej chvíli by sa mal vyplniť TextField s adresou servera a portom a tlačidlo na pripojenie by malo byť aktívny. Po kliknutí na tlačidlo by sa mal zobraziť dialóg, že pripojenie prebehlo úspešne a tlačidlo pripojenia by opäť nemalo byť aktívny. Naopak tlačidlo pripojenia by sa malo aktivovať. Že ste sa naozaj pripojili spoznáte najlepšie tak, že sa zmení u pripojeného servera počet pripojených užívateľov.

Úspešné pripojenie na server - Server pre klientskej aplikácie v Jave

To by bolo pre dnešné lekciu všetko. Nabudúce, v lekcii Java chat - Server - Správa užívateľov , vytvoríme jednoduchú správu užívateľov na strane servera a prihlásime sa na server pod prezývkou.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 15x (121.04 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Java chat - Klient - Spojenie so serverom 2. časť
Všetky články v sekcii
Server pre klientskej aplikácie v Jave
Preskočiť článok
(neodporúčame)
Java chat - Server - Správa užívateľov
Článok pre vás napísal Petr Štechmüller
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity