Server-Client (Networking)

Communication between two Java apps using CheerpJ and Tailscale.

This tutorial runs two Java applications in the browser with CheerpJ, a server and a client, and connects them over TCP with java.net.ServerSocket and java.net.Socket. Browsers do not give web pages access to TCP sockets, so the two applications connect through a Tailscale network.

For how CheerpJ and Tailscale work together, see the Networking guide. The finished project is in the examples/Server-Client directory of the cheerpj-meta repository.

A server app and a client app, each running in CheerpJ in its own browser tab, using java.net.ServerSocket and java.net.Socket, connected over WebSockets through the Tailscale VPN (WireGuard over WebSockets)

Prerequisites

  • A text editor to create and edit an HTML file
  • A local HTTP server that supports Range requests, such as npx http-server
  • A modern browser such as Chrome, Edge, Firefox or Safari
  • A Tailscale account (see step 2)

1. The Java applications

The example is a chat room: a Java server application and a Java client application that exchange messages over sockets. It is based on a TechVidvan tutorial, which explains the source code.

Both applications run in the browser with CheerpJ, with no Java installation.

Client Server

2. Tailscale

As the Networking guide explains, CheerpJ supports networking other than HTTP(S), such as TCP and UDP sockets, through Tailscale. Tailscale is a VPN based on WireGuard, which CheerpJ reaches over WebSockets.

2.1 Setting up Tailscale

Create a Tailscale network and connect both Java applications to it as nodes. In Tailscale terminology, a node is a combination of a user and a device connected to the network.

  1. Create a Tailscale account and log in. Creating an account creates a network (a tailnet).
  2. Generate two auth keys, one for each application, in the Tailscale admin console, or one reusable key. Keep them for later: the applications use them to join the tailnet.
Tailscale auth keys
Choose the options in the Tailscale keys menu that suit you. Each time a page starts CheerpJ with a key it adds a node to the tailnet. To keep within your Tailscale device quota, use ephemeral keys or remove unused devices from the admin console.

3. Setting up the project

Create a project directory with two subdirectories, one for the server and one for the client:

  1. Create the project directory tree:
Terminal window
mkdir -p ServerClientTutorial/{Server,Client}
  1. Put each application’s JAR in its directory:
  2. Create an HTML file in each subdirectory: server.html in Server and client.html in Client. The project tree looks like this:
└──ServerClientTutorial
├── Server
│ ├── Server.jar
│ └── server.html
└── Client
├── Client.jar
└── client.html

3.1 The Server application

  1. Add this code to server.html:
server.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Server</title>
<script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script>
</head>
<body>
<input type="text" id="ip" />
<script>
(async function () {
await cheerpjInit({
tailscaleAuthKey: "PasteYourKeyHere",
tailscaleIpCb: (ip) => {
let el = document.querySelector("#ip");
el.value = ip;
},
});
cheerpjCreateDisplay(800, 600);
await cheerpjRunJar("/app/Server.jar");
})();
</script>
</body>
</html>

What is happening here?

  • The <script> tag in the <head> loads CheerpJ.
  • cheerpjInit initialises CheerpJ. The tailscaleAuthKey option passes the auth key that the application uses to join the tailnet.
  • tailscaleIpCb is called with the application’s IP address on the tailnet once it is connected. The page writes it into the input field so you can copy it.
  • cheerpjCreateDisplay creates an 800x600 display that holds all Java windows.
  • cheerpjRunJar runs the server application.
  • /app/ is the virtual file system mount point for the root of the web server the page is loaded from.
  1. Replace “PasteYourKeyHere” with the first auth key.
  2. Serve the page with an HTTP server started inside the Server directory:
Terminal window
cd ServerClientTutorial/Server
npx http-server -p 8080
  1. Open http://127.0.0.1:8080/server.html in a browser tab.
  2. CheerpJ shows its loading animation, then the server application starts.
  3. Once the server is connected to the tailnet, its IP address appears in the field above the display. Keep it: the client needs it to connect. The address is also listed in the Tailscale admin console.

3.2 The Client application

  1. Add this code to client.html:
client.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Client</title>
<script src="https://cjrtnc.leaningtech.com/5.0/loader.js"></script>
</head>
<body>
<input type="text" id="ip" />
<script>
async function start(ip) {
await cheerpjInit({
tailscaleAuthKey: "PasteYourKeyHere",
});
cheerpjCreateDisplay(800, 600);
await cheerpjRunJar("/app/Client.jar", ip);
}
let el = document.querySelector("#ip");
el.addEventListener("keydown", (e) => {
if (e.key == "Enter") {
start(el.value);
}
});
</script>
</body>
</html>

What is happening here?

  • The page waits for you to type the server’s IP address in the input field and press Enter, then starts CheerpJ.
  • The second argument of cheerpjRunJar is passed to the Java main method in args. Here it is the server’s Tailscale IP address, which the client connects to.
  1. Replace “PasteYourKeyHere” with the second auth key.
  2. Serve the page with an HTTP server started inside the Client directory, on a different port from the server’s:
Terminal window
cd ServerClientTutorial/Client
npx http-server -p 8081
  1. Open http://127.0.0.1:8081/client.html in another browser tab.
  2. Paste the server’s IP address in the input field and press Enter.
  3. CheerpJ shows its loading animation, then the client application starts and connects to the server.

4. Final test

With both applications running, enter a username and connect in each of them. Then send messages from one application to the other.

Server Browser

Client Browser

View full source code on GitHub

Credits

The Java applications used in this tutorial belong to TechVidvan. Their tutorial includes the source code. The applications have been lightly edited for this tutorial.

Further reading

Build with Java for the browser.