登录
ZH

教程:建立 TCP 连接,一步一步来

示例项目 apps/hello-tcp 打开一个到 Redis 服务器的 TCP 连接,向它发送 PING 并显示响应(+PONG)。同样的代码 既能在电脑上运行(套接字),也能在浏览器中运行(jumphp.net 的 TCP 网桥)。用 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 服务器(一个回复 +PONG 的假 Redis),点击 按钮,推进若干帧,并检查显示的文本。

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

在浏览器中,页面无法打开套接字:连接要经过 jumphp.net 的 TCP 网桥。它只放行经管理员批准的 应用,针对代码的某个特定版本,可连接公共地址的任意端口(出站邮件 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. 管理员在他的铃铛中看到申请,并批准(或拒绝):批准针对已发布的 commit。新的 commit 需要新的批准。

8. 验证

打开 jumphp.net 上的项目页面,输入一个公共 Redis(或你自己的,端口 6379)的地址并点击:The server answered: +PONG。管理员可以实时看到这个连接 (Administration → Pont TCP:应用、目标、时长、字节数),并可以将其切断。

进一步阅读:docs/tcp.md(权限、防护措施、独立服务器上的网桥),docs/tuto-ssh.md(通过 SSH 服务器实现同样的功能),UDP ($this->engine->udp())和 ping($this->engine->icmp())在同一份文档中。