Office week Slevový týden - Květen
Pouze tento týden sleva až 80 % na e-learning týkající se MS Office
30 % bodů zdarma na online výuku díky naší Slevové akci!

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()));
});
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

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

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.


 

Stiahnuť

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

 

 

Článok pre vás napísal Petr Štechmüller
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v Jave, ale nebojí se ani webových technologií.
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
Miniatúra
Nasledujúci článok
Java chat - Server - Správa užívateľov
Aktivity (1)

 

 

Komentáre

Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!