You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP客户端连接Jupyter Server ZMQ无响应问题求助

无法通过PHP ZMQ脚本与Jupyter Server建立连接并获取响应

我尝试用PHP脚本发送ZMQ消息与Jupyter Server通信,但连接无法正常建立,也无法获取响应。

我的Jupyter Notebook配置文件~/.jupyter/jupyter_notebook_config.py内容如下:

c.NotebookApp.ip = '127.0.0.1'
c.NotebookApp.port = 9992
c.Session.key = b'00f2400c-bea977d0c80f0'
c.ConnectionFileMixin.shell_port = 37971
c.ConnectionFileMixin.iopub_port = 36612
c.ConnectionFileMixin.control_port = 51091
c.ConnectionFileMixin.hb_port = 55613
c.NotebookApp.token = '12345'
c.ConnectionFileMixin.ip = '0.0.0.0'
c.KernelManager.autorestart = True

用于连接的PHP脚本:

<?php

// Load the ZMQ extension
$context = new ZMQContext();

// Create a new socket of type Request (REQ)
$socket = $context->getSocket(ZMQ::SOCKET_REQ);

// Connect to the server
$socket->connect("tcp://127.0.0.1:55613");

for ($request = 0; $request < 10; $request++)
{
    echo "Sending request $request...\n";

    // Command to send.
    $socket->send("Heartbeat");

    // Get the reply.
    $reply = $socket->recv();

    echo "Received reply $request: [$reply]\n";
}

启动Notebook后运行该PHP脚本,服务器无任何响应返回,脚本仅输出Sending request 0...,之后一直卡在等待回复的状态。


问题分析与解决方案

1. 核心错误:连接了错误的端口

你当前连接的55613是Jupyter的心跳端口(hb_port),这个端口仅用于Jupyter内核与服务器之间的存活检测,不处理外部REQ-REP请求,也不会返回任何响应,这是脚本卡住的直接原因。

2. 选择正确的通信端口

要与Jupyter内核进行有效通信,应该连接shell_port(37971)或control_port(51091):

  • shell_port:用于执行代码、查询内核状态等常规交互操作
  • control_port:用于发送控制类命令(如中断内核、重启内核)

3. 遵循Jupyter ZMQ通信协议

即使连接了正确的端口,直接发送"Heartbeat"字符串也无法被Jupyter识别——Jupyter的ZMQ通信遵循Jupyter Messaging Protocol,所有消息必须是符合规范的JSON结构,且需要通过配置的Session.key进行加密签名。

简化测试脚本(跳过签名,验证连接)

如果只是想验证ZMQ连接是否正常,可以先临时关闭消息签名:

  • 修改jupyter_notebook_config.py,注释掉c.Session.key配置项
  • 重启Jupyter Notebook

使用以下脚本连接shell_port,发送内核信息查询命令:

<?php
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_REQ);
// 连接shell端口
$socket->connect("tcp://127.0.0.1:37971");

// 构造符合Jupyter协议的消息结构
$msg = [
    'header' => [
        'msg_id' => uniqid(),
        'username' => 'php-client',
        'session' => uniqid(),
        'msg_type' => 'kernel_info_request',
        'version' => '5.3'
    ],
    'parent_header' => [],
    'metadata' => [],
    'content' => []
];

// Jupyter消息需要分帧发送:签名、分隔符、各字段JSON
$socket->sendMulti([
    '', // 无签名时传空字符串
    '<IDS|MSG>',
    json_encode($msg['header']),
    json_encode($msg['parent_header']),
    json_encode($msg['metadata']),
    json_encode($msg['content'])
]);

// 接收多帧响应并解析内容
$responseFrames = $socket->recvMulti();
$content = json_decode($responseFrames[5], true);
print_r($content);

其他注意事项

  • 确保PHP的ZMQ扩展版本与Jupyter使用的ZMQ版本兼容
  • 检查本地防火墙/端口占用情况,确保目标端口可正常访问
  • 如果需要完整加密通信,需实现Jupyter的HMAC签名逻辑,用配置的Session.key对消息内容进行签名

内容的提问来源于stack exchange,提问作者techwoman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:05:09