Sign in
EN

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

  1. Push the project to Git and publish it on jumphp.net (see « Avec votre Claude » or the IDE: Mettre sur jumphp.net).
  2. Studio → the project → Accès TCP → « Demander l'accès TCP » (with a message for the administrator if you like).
  3. 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.