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

如何使用Laravel(或PHP)作为客户端订阅外部服务器的SSE事件流?

用Laravel/PHP作为客户端订阅外部SSE事件流

原生PHP实现

SSE本质是HTTP长连接,客户端需要持续读取服务器返回的流式响应,可通过stream_context_create和fopen实现基础订阅逻辑:

$sseUrl = 'https://external-server.com/events';

// 配置HTTP上下文,禁用超时以维持长连接
$context = stream_context_create([
    'http' => [
        'timeout' => 0,
        'header' => "Accept: text/event-stream\r\n" .
                    "Connection: keep-alive\r\n"
    ]
]);

$stream = fopen($sseUrl, 'r', false, $context);

if (!$stream) {
    die('无法连接到SSE服务器');
}

// 持续读取流式响应
while (!feof($stream)) {
    $line = fgets($stream);
    
    // 跳过SSE协议中的空行分隔符
    if (trim($line) === '') {
        continue;
    }
    
    // 解析SSE的data字段内容
    if (str_starts_with($line, 'data:')) {
        $data = trim(substr($line, 5));
        // 此处可添加业务处理逻辑,比如写入日志、触发内部事件等
        echo "收到SSE数据: {$data}\n";
    }
}

fclose($stream);

Laravel集成实现

在Laravel中推荐用Artisan命令封装订阅逻辑,方便后台运行与进程管理:

1. 创建订阅命令

执行php artisan make:command SubscribeSse生成命令文件,修改内容如下:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class SubscribeSse extends Command
{
    protected $signature = 'sse:subscribe';
    protected $description = '订阅外部SSE事件流';

    public function handle()
    {
        $sseUrl = config('services.sse.external_url');
        $retryDelay = 5; // 断线重连间隔(秒)

        while (true) {
            try {
                $context = stream_context_create([
                    'http' => [
                        'timeout' => 0,
                        'header' => "Accept: text/event-stream\r\nConnection: keep-alive\r\n"
                    ]
                ]);

                $stream = fopen($sseUrl, 'r', false, $context);

                if (!$stream) {
                    throw new \Exception('无法建立SSE连接');
                }

                $this->info('已连接到SSE服务器,开始接收数据...');

                while (!feof($stream)) {
                    $line = fgets($stream);
                    if (trim($line) === '') {
                        continue;
                    }

                    // 可扩展解析event、id等SSE字段
                    if (str_starts_with($line, 'data:')) {
                        $data = trim(substr($line, 5));
                        $this->info("收到数据: {$data}");
                        
                        // 触发Laravel内部事件,对接业务逻辑
                        // event(new ExternalSseReceived($data));
                    }
                }

                fclose($stream);
            } catch (\Exception $e) {
                $this->error("连接异常: {$e->getMessage()}");
                Log::error('SSE订阅失败', ['message' => $e->getMessage()]);
            }

            $this->info("{$retryDelay}秒后尝试重连...");
            sleep($retryDelay);
        }
    }
}

2. 配置SSE地址

在config/services.php中添加配置项:

'sse' => [
    'external_url' => env('EXTERNAL_SSE_URL'),
],

然后在.env文件中设置目标SSE地址:EXTERNAL_SSE_URL=https://external-server.com/events

3. 运行与管理

执行php artisan sse:subscribe即可启动订阅。如需后台持久运行,可使用nohup php artisan sse:subscribe &,或通过Supervisor等进程管理器保障服务稳定性。

关键注意事项

  • 断线重连:SSE连接易因网络波动中断,必须实现自动重试逻辑
  • 资源监控:长连接会占用进程资源,建议用进程管理器监控运行状态
  • 协议解析:可扩展解析SSE的event、id、retry字段,适配不同的服务器返回格式
  • 超时设置:禁用HTTP超时,确保长连接可持续维持

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:36:18