Tutorial: a TCP connection, step by step
The example project apps/hello-tcp opens a TCP connection to a Redis server, sends it PING and shows the answer (+PONG). The same code
works on a computer (a socket) and in the browser (jumphp.net's TCP bridge). Redo it yourself in 8 steps.
1. Create the application
bin/jumphp gui:new mon-tcp "Mon TCP" # apps/mon-tcp : une application graphique (formulaires, pas de HTML)
bin/jumphp install mon-tcp
2. Draw the window
Open apps/mon-tcp/forms/MainForm.form.yaml (in the IDE: the visual editor, Design tab): two fields (host, port), a ping button
(events: {click: onPingClick}), two labels (status, result). Copy the one from apps/hello-tcp/forms/MainForm.form.yaml.
3. Write the code behind
apps/mon-tcp/src/Form/MainForm.php: a class final class MainForm extends JumPHP\Gui\Form. One @property line per widget (the editor does it for you).
public function onPingClick(mixed $sender = null): void
{
$connection = $this->engine->tcp()->connect(trim($this->host->text), (int)$this->port->text); // ne bloque jamais
$connection->on('open', fn () => $connection->write("PING\r\n")); // connecté : on parle
$connection->on('data', function (string $bytes) use ($connection) { // la réponse
$this->result->text = 'Réponse : ' . trim($bytes);
$connection->close();
});
$connection->on('error', fn (string $message) => $this->result->text = $message); // le pourquoi d'un échec
}
The rules to remember: never call stream_socket_client or fsockopen (they do not exist in the browser); never wait: the answers arrive
as events between two frames. The events: open, data (bytes), close (the reason, or null), error (a message).
4. A test that plays the scene
apps/mon-tcp/tests/MainFormTest.php (see apps/hello-tcp/tests/MainFormTest.php): the test opens a real local TCP server (a fake Redis that answers +PONG), clicks the
button, advances the frames and checks the displayed text.
bin/jumphp test mon-tcp # php -l, phpstan, phpunit (le test ci-dessus), puis 600 images de la scène
bin/jumphp shot mon-tcp # une capture : ouvrez le PNG (apps/mon-tcp/var/screenshots/shot.png)
5. Try it on your computer
bin/jumphp run mon-tcp # une vraie fenêtre ; entrez l'adresse d'un Redis et cliquez « Send PING »
6. Try it in the browser
bin/jumphp build mon-tcp && bin/jumphp serve mon-tcp # http://localhost:8080
In the browser, a page cannot open a socket: the connection goes through jumphp.net's TCP bridge. It only lets through applications approved by the
administrator, for a precise version of the code, to any port (except outgoing mail 25 / 465 / 587) of public addresses. Without approval, the
error event says why (« This application has no TCP right… »). This is the expected behaviour: go on to step 7.
7. Publish and request TCP access
- Push the project to Git and publish it on jumphp.net (see « Avec votre Claude » or the IDE: Mettre sur jumphp.net).
- Studio → the project → Accès TCP → « Demander l'accès TCP » (with a message for the administrator if you like).
- The administrator sees the request in their bell and approves it (or refuses): the approval is valid for the published commit. A new commit needs a new approval.
8. Check
Open the project page on jumphp.net, enter the address of a public Redis (or your own, port 6379) and click: The server answered: +PONG. The administrator sees the connection
live (Administration → Pont TCP: application, target, duration, bytes) and can cut it.
To go further: docs/tcp.md (the rights, the safeguards, the bridge on an independent server), docs/tuto-ssh.md (the same through an SSH server), UDP
($this->engine->udp()) and pings ($this->engine->icmp()) in the same document.