RU

Руководство: TCP-соединение, шаг за шагом

Пример проекта apps/hello-tcp открывает TCP-соединение с сервером Redis, отправляет ему PING и показывает ответ (+PONG). Один и тот же код работает на компьютере (сокет) и в браузере (TCP-мост jumphp.net). Повторите это сами за 8 шагов.

1. Создать приложение

bin/jumphp gui:new mon-tcp "Mon TCP"        # apps/mon-tcp : une application graphique (formulaires, pas de HTML)
bin/jumphp install mon-tcp

2. Нарисовать окно

Откройте apps/mon-tcp/forms/MainForm.form.yaml (в IDE: визуальный редактор, вкладка Design): два поля (host, port), кнопка ping (events: {click: onPingClick}), две надписи (status, result). Скопируйте файл из apps/hello-tcp/forms/MainForm.form.yaml.

3. Написать код за окном

apps/mon-tcp/src/Form/MainForm.php: класс final class MainForm extends JumPHP\Gui\Form. Одна строка @property на виджет (редактор делает это за вас).

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
}

Правила, которые стоит запомнить: никогда не вызывайте stream_socket_client или fsockopen (их нет в браузере); никогда не ждите: ответы приходят как события между двумя кадрами. События: open, data (байты), close (причина или null), error (сообщение).

4. Тест, который проигрывает сцену

apps/mon-tcp/tests/MainFormTest.php (см. apps/hello-tcp/tests/MainFormTest.php): тест открывает настоящий локальный TCP-сервер (поддельный Redis, отвечающий +PONG), нажимает кнопку, прокручивает кадры и проверяет показанный текст.

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. Попробовать на своём компьютере

bin/jumphp run mon-tcp           # une vraie fenêtre ; entrez l'adresse d'un Redis et cliquez « Send PING »

6. Попробовать в браузере

bin/jumphp build mon-tcp && bin/jumphp serve mon-tcp      # http://localhost:8080

В браузере страница не может открыть сокет: соединение проходит через TCP-мост jumphp.net. Он пропускает только приложения, разрешённые администратором, для конкретной версии кода, на любой порт (кроме исходящей почты 25 / 465 / 587) публичных адресов. Без разрешения событие error объясняет почему (« This application has no TCP right… »). Это ожидаемое поведение: переходите к шагу 7.

7. Опубликовать и запросить доступ TCP

  1. Отправьте проект в Git и опубликуйте его на jumphp.net (см. « Avec votre Claude » или IDE: Mettre sur jumphp.net).
  2. Studio → проект → Accès TCP → « Demander l'accès TCP » (при желании с сообщением для администратора).
  3. Администратор видит запрос в своём колокольчике и разрешает его (или отклоняет): разрешение действует для опубликованного коммита. Новый коммит требует нового разрешения.

8. Проверить

Откройте страницу проекта на jumphp.net, введите адрес публичного Redis (или своего, порт 6379) и нажмите: The server answered: +PONG. Администратор видит соединение в реальном времени (Administration → Pont TCP: приложение, цель, длительность, байты) и может его отключить.

Чтобы пойти дальше: docs/tcp.md (права, защитные меры, мост на независимом сервере), docs/tuto-ssh.md (то же самое через SSH-сервер), UDP ($this->engine->udp()) и пинги ($this->engine->icmp()) в том же документе.