如何使用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
相关产品推荐
相关产品推荐

