Implement example chat app

This commit is contained in:
ChronosX88 2023-12-12 00:53:05 +03:00
parent 6a5eab54cb
commit 9f8898561d
5 changed files with 123 additions and 16 deletions

View File

@ -17,7 +17,6 @@ repositories {
dependencies {
api 'org.java-websocket:Java-WebSocket:1.5.4'
compileOnly 'org.java-websocket:Java-WebSocket:1.5.4'
implementation 'net.sourceforge.streamsupport:android-retrofuture:1.7.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.3'
implementation 'com.github.ben-manes.caffeine:jcache:3.1.5'

View File

@ -1,20 +1,82 @@
package io.github.chronosxyz.JGUN.examples.chat;
import io.github.chronosx88.JGUN.api.Gun;
import io.github.chronosx88.JGUN.api.graph.ArrayBuilder;
import io.github.chronosx88.JGUN.api.graph.NodeBuilder;
import io.github.chronosx88.JGUN.models.graph.Node;
import io.github.chronosx88.JGUN.models.graph.NodeValue;
import io.github.chronosx88.JGUN.models.graph.values.ArrayValue;
import io.github.chronosx88.JGUN.models.graph.values.NodeLinkValue;
import io.github.chronosx88.JGUN.models.graph.values.StringValue;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
public class FXMLController implements Initializable {
@FXML
private Label label;
Button sendButton;
@FXML
TextArea chatBox;
@FXML
TextArea msgEditbox;
@FXML
TextField nicknameEditbox;
private Gun gun;
@Override
public void initialize(URL url, ResourceBundle rb) {
String javaVersion = System.getProperty("java.version");
String javafxVersion = System.getProperty("javafx.version");
label.setText("Hello, JavaFX " + javafxVersion + "\nRunning on Java " + javaVersion + ".");
Platform.runLater(() -> {
gun.get("chat").map((k, v) -> {
if (!k.equals("messages")) return;
ArrayValue val = (ArrayValue) v;
val.getValue().forEach((e) -> {
if (e.getValueType() == NodeValue.ValueType.LINK) {
Node obj;
try {
obj = gun.get(((NodeLinkValue) e).getLink()).once().get().getData();
} catch (InterruptedException | ExecutionException ex) {
throw new RuntimeException(ex);
}
StringValue fromVal = (StringValue) obj.getValues().get("from");
StringValue msgVal = (StringValue) obj.getValues().get("text");
StringValue dateVal = (StringValue) obj.getValues().get("date");
chatBox.appendText(String.format("[%s] <%s> %s\n", dateVal.getValue(), fromVal.getValue(), msgVal.getValue()));
}
});
});
});
sendButton.setOnAction((e) -> {
try {
gun.get("chat")
.put(new NodeBuilder().add("messages", new ArrayBuilder()
.add(new NodeBuilder()
.add("date", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(Calendar.getInstance().getTime()))
.add("from", nicknameEditbox.getText())
.add("text", msgEditbox.getText()))).build())
.get();
} catch (InterruptedException | ExecutionException ex) {
throw new RuntimeException(ex);
}
msgEditbox.clear();
});
}
public void setGunInstance(Gun gun) {
this.gun = gun;
}
}

View File

@ -0,0 +1,14 @@
package io.github.chronosxyz.JGUN.examples.chat;
import io.github.chronosx88.JGUN.api.Gun;
import io.github.chronosx88.JGUN.network.GatewayNetworkNode;
import io.github.chronosx88.JGUN.storage.MemoryStorage;
import io.github.chronosx88.JGUN.storage.Storage;
public class Gateway {
public static void main(String[] args) throws InterruptedException {
Storage storage = new MemoryStorage();
GatewayNetworkNode peer = new GatewayNetworkNode(5054, storage);
Gun gun = new Gun(storage, peer);
}
}

View File

@ -1,10 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1"
<SplitPane dividerPositions="0.8442211055276382" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="io.github.chronosxyz.JGUN.examples.chat.FXMLController">
<Label fx:id="label" text="Label"/>
</StackPane>
<items>
<AnchorPane maxHeight="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" prefHeight="374.0"
prefWidth="598.0">
<children>
<TextArea fx:id="chatBox" editable="false" prefHeight="333.0" prefWidth="598.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0"/>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0"
SplitPane.resizableWithParent="false">
<children>
<HBox alignment="CENTER" prefHeight="59.0" prefWidth="598.0" spacing="10.0"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="0.0">
<children>
<TextField fx:id="nicknameEditbox" prefHeight="34.0" prefWidth="208.0" promptText="Nickname"/>
<TextArea fx:id="msgEditbox" prefHeight="200.0" prefWidth="200.0" promptText="Message"
wrapText="true" HBox.hgrow="ALWAYS"/>
<Button fx:id="sendButton" mnemonicParsing="false" text="Send"/>
</children>
</HBox>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
</AnchorPane>
</items>
</SplitPane>

View File

@ -26,8 +26,8 @@ public class GatewayNetworkNode extends WebSocketServer implements Peer {
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
if(conn != null) {
System.out.println("Peer " + conn.getRemoteSocketAddress().toString() + " closed the connection for reason (code): " + reason + " (" + code + ")");
if (conn != null) {
System.out.println("Peer " + conn + " closed the connection for reason (code): " + reason + " (" + code + ")");
}
}
@ -38,7 +38,7 @@ public class GatewayNetworkNode extends WebSocketServer implements Peer {
@Override
public void onError(WebSocket conn, Exception ex) {
if(conn != null) {
if (conn != null) {
System.out.println("# Exception occurred on connection: " + conn.getRemoteSocketAddress());
}
ex.printStackTrace();
@ -50,7 +50,7 @@ public class GatewayNetworkNode extends WebSocketServer implements Peer {
}
public void emit(String data) {
for(WebSocket conn : this.getConnections()) {
for (WebSocket conn : this.getConnections()) {
conn.send(data);
}
}