海康威视DeepView摄像头ISAPI alertStream端点集成问题求助
解决海康威视DeepView摄像头ISAPI alertStream端点的curl流式响应问题
海康的ISAPI/Event/notification/alertStream是HTTP流式接口,采用Chunked编码持续推送告警事件,这就是你遇到问题的核心原因:
- 当
CURLOPT_RETURNTRANSFER=true时,curl会一直等待连接断开才返回完整响应,但这个接口会保持长连接持续推送,所以永远拿不到完整结果 - 当
CURLOPT_RETURNTRANSFER=false时,curl会把收到的每一段流式数据直接输出到终端stdout,所以你能看到内容但无法在代码里处理
解决方案:使用curl的写入回调函数捕获流式输出
通过CURLOPT_WRITEFUNCTION自定义处理每一段收到的数据,既能在代码中捕获内容,又不用等待连接关闭。以下是适配Symfony命令的修改代码:
protected function execute(InputInterface $input, OutputInterface $output): int { // 用来存储流式响应的内容(用引用传递给回调) $responseBuffer = ''; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://你的摄像头IP/ISAPI/Event/notification/alertStream'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_USERPWD, '用户名:密码'); // 设置写入回调:每次收到数据时追加到buffer curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) use (&$responseBuffer, $output) { $responseBuffer .= $data; // 这里可以实时处理收到的单条告警(比如解析XML/JSON) // 示例:输出到Symfony命令的控制台(可选) $output->write($data); // 返回收到的数据长度,告诉curl已处理完成 return strlen($data); }); // 执行请求(因为是长连接,会一直阻塞直到连接断开或手动终止) curl_exec($ch); if (curl_errno($ch)) { $output->writeln('<error>Error: ' . curl_error($ch) . '</error>'); } curl_close($ch); // 如果需要最后返回完整buffer(注意:长连接下只有断开后才会走到这) // $output->writeln('Final response: ' . $responseBuffer); return Command::SUCCESS; }
额外提示
- 手动终止长连接:因为alertStream是持续推送的,Symfony命令会一直阻塞,你可以通过监听信号(比如
SIGINT即CTRL+C)来优雅关闭curl句柄,避免进程强制终止:
// 在execute方法开头添加 pcntl_signal(SIGINT, function() use ($ch) { if ($ch) { curl_close($ch); exit(Command::SUCCESS); } });
- 解析告警内容:海康的alertStream返回的是XML格式的事件数据,你可以在回调函数中每次收到数据后,按XML节点分割解析(注意Chunked编码的每一段可能是完整或部分XML,需要处理拼接)。
- 超时设置:如果需要自动断开连接,可以添加
CURLOPT_TIMEOUT或CURLOPT_CONNECTTIMEOUT选项设置超时时间。
内容的提问来源于stack exchange,提问作者arosa
相关产品推荐
相关产品推荐

