Geek tričko zdarma Python týden
Tričko zdarma! Stačí před dobitím bodů použít kód TRIKO15. Více informací zde
Pouze tento sleva až 80% na kurzy Python

Lekce 19 - Java chat - Klient - Spojení se serverem 3. část

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Java chat - Klient - Spojení se serverem 2. část, jsme se věnovali implementaci klientského komunikátoru. V dnešním Java tutoriálu konečně vytvoříme stabilní spojení se serverem.

Upravení připojovacího kontroleru

Začneme upravením třídy ConnectController. Ve třídě vytvoříme novou instanční proměnnou typu IClientCommunicationService. Rovnou této proměnné vytvoříme setter, abychom mohli komunikátor nastavit:

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 nastavovat, protože nemáme v projektu implementovanou žádnou správu závislostí, jako tomu bylo u serveru. Dále v setteru vytváříme BooleanProperty connected, na kterou bindujeme disableProperty tlačítek pro připojení a odpojení. DisableProperty tlačítka "připojit" má trošku složitější logiku, protože se musíme ještě dívat, zda-li se máme k čemu připojit (je vyplněn TextField se serverem).

Dále upravíme metodu initialize(), do které přidáme reakci na výběr 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()));
});

Voláním metod getSelectionModel().selectedItemProperty() získáme pozorovatelnou read-only property, na kterou přidáme listener, který se zavolá vždy, když změníme výběr položky v listView. Pokud bude nová hodnota null, tak nic dělat nebudeme, v opačném případě vyplníme TextField txtServer hodnotou ve formátu: "server:port".

Nyní vytvoříme nejdůležitější metodu v kontroleru, connect(), pomocí které se budeme připojovat 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 první části metody parsujeme z TextFieldu adresu serveru a port, na kterém server naslouchá. Pokud se nepodaří naparsovat port serveru, zobrazíme upozornění uživateli, že port není ve validním stavu. Následuje zavolání metody connect() nad instancí našeho komunikátoru. Metodou exceptionaly() ošetříme případ, kdy se spojení nepodařilo navázat. Když se jednou dostaneme do větve exceptionaly(), můžeme v ní zůstat tak, že opět vyhodíme nějakou výjimku, nebo vrátíme smysluplnou hodnotu, čímž se dostaneme do výchozí větve. Větev thenAccept() je zavolána v případě, že spojení se úspěšně vytvořilo.

Nakonec nám už jenom zbývá nastavit odpovídajícím tlačítkům správnou akci:

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

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

Upravení hlavního kontroleru

Nyní se přesuneme do hlavního kontroleru, ve kterém budeme držet jedinou instanci komunikátoru. Vytvoříme tedy ve třídě MainController instanční konstantu komunikátoru:

private final IClientCommunicationService communicator = new ClientCommunicationService();

Dále upravíme metodu handleConnect(), ve které voláme zobrazení 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();
    }
}

Metoda showNewWindow() vrací kontroler nového okna. Tento kontroler si uložíme do lokální proměnné a metodou setCommunicator() nastavíme kontroleru komunikátor.

Ještě využijeme metodu onClose(), která se zavolá při zavření okna. V této metodě se pro jistotu odpojíme od serveru. Tím bezpečně ukončíme spojení a veškerá vlákna s ním spojená:

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

Testování funkčnosti

Konečně se můžeme připojit k serveru. Z předchozí lekce máme funkční vyhledávání lokálních serverů, tak toho hned využijeme. Spustíme server a klienta. Dále zobrazíme okno pro připojení. Když se zobrazí v seznamu náš spuštěný server, klikneme na tuto položku. V té chvíli by se měl vyplnit TextField s adresou serveru a portem a tlačítko na připojení by mělo být aktivní. Po kliknutí na tlačítko by se měl zobrazit dialog, že připojení proběhlo úspěšně a tlačítko pro připojení by opět nemělo být aktivní. Naopak tlačítko pro připojení by se mělo aktivovat. Že jste se opravdu připojili poznáte nejlépe tak, že se změní u připojeného serveru počet připojených uživatelů.

Úspěšné připojení k serveru

To by bylo pro dnešní lekci vše. Příště, v lekci Java chat - Server - Správa uživatelů, vytvoříme jednoduchou správu uživatelů na straně serveru a přihlásíme se na server pod přezdívkou.


 

Stáhnout

Staženo 10x (123.28 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

 

Článek pro vás napsal Petr Štechmüller
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje primárně programování v Jave, ale nebojí se ani webových technologií.
Předchozí článek
Java chat - Klient - Spojení se serverem 2. část
Všechny články v sekci
Server pro klientské aplikace v Javě
Miniatura
Následující článek
Java chat - Server - Správa uživatelů
Aktivity (2)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!