|
@@ -10,6 +10,7 @@ use App\Libs\Utils;
|
|
|
use App\Services\DeepSeek\DeepSeekService;
|
|
|
use Illuminate\Http\Request;
|
|
|
use Illuminate\Routing\Controller as BaseController;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
use Illuminate\Support\Facades\Redis;
|
|
|
use Illuminate\Support\Facades\Validator;
|
|
|
|
|
@@ -77,4 +78,113 @@ class DeepSeekController extends BaseController
|
|
|
$result = $this->deepseekService->setStsToken($data);
|
|
|
return $this->success($result);
|
|
|
}
|
|
|
+
|
|
|
+ public function sseLink(Request $request) {
|
|
|
+ $data = $request->all();
|
|
|
+ $bid = getProp($data, 'bid');
|
|
|
+ $version_id = getProp($data, 'version_id');
|
|
|
+ $cid = getProp($data, 'cid');
|
|
|
+
|
|
|
+ // 禁用输出缓冲
|
|
|
+ while (ob_get_level()) ob_end_clean();
|
|
|
+
|
|
|
+ // 设置SSE所需的HTTP头
|
|
|
+ header('Content-Type: text/event-stream');
|
|
|
+ header('Cache-Control: no-cache');
|
|
|
+ header('Connection: keep-alive');
|
|
|
+ header('X-Accel-Buffering: no'); // 防止Nginx缓冲
|
|
|
+
|
|
|
+ // 允许跨域请求(根据需求设置)
|
|
|
+ header('Access-Control-Allow-Origin: *');
|
|
|
+ header('Access-Control-Allow-Credentials: true');
|
|
|
+
|
|
|
+ // 设置脚本执行时间无限
|
|
|
+ set_time_limit(0);
|
|
|
+
|
|
|
+ // 手动刷新输出缓冲区
|
|
|
+ ob_implicit_flush(true);
|
|
|
+ if(ob_get_level()>0) ob_flush();
|
|
|
+ flush();
|
|
|
+
|
|
|
+ // 客户端ID(用于多用户区分)
|
|
|
+ $clientId = $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'];
|
|
|
+ $lastEventId = isset($_SERVER['HTTP_LAST_EVENT_ID']) ? intval($_SERVER['HTTP_LAST_EVENT_ID']) : 0;
|
|
|
+ // dd($clientId, $lastEventId);
|
|
|
+
|
|
|
+ // 发送初始欢迎消息
|
|
|
+ $this->sendEvent([
|
|
|
+ // 'message' => "欢迎使用SSE服务! 你的客户端ID: {$clientId}",
|
|
|
+ // 'type' => 'info',
|
|
|
+ // 'timestamp' => date('H:i:s')
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => "已连接! 你的客户端ID: {$clientId}",
|
|
|
+ 'data' => [],
|
|
|
+ ]);
|
|
|
+
|
|
|
+ if (!$bid && !$version_id && !$cid) {
|
|
|
+ $this->sendEvent([
|
|
|
+ // 'message' => '参数异常',
|
|
|
+ // 'type' => 'error',
|
|
|
+ // 'timestamp' => date('H:i:s')
|
|
|
+ 'code' => -1,
|
|
|
+ 'msg' => "参数异常",
|
|
|
+ 'data' => [],
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计数器
|
|
|
+ $counter = 0;
|
|
|
+ $tmp_url_count = 0;
|
|
|
+
|
|
|
+ // 主循环 - 定期发送数据
|
|
|
+ while (true) {
|
|
|
+ // 检查客户端是否断开连接
|
|
|
+ if (connection_aborted()) {
|
|
|
+ exit();
|
|
|
+ }
|
|
|
+
|
|
|
+ $counter++;
|
|
|
+ if ($counter % 10 == 0) {
|
|
|
+ // 每10s判断是否有新url生成,如果有则发送消息
|
|
|
+ $paragraph_urls = DB::table('mp_chapter_paragraph_audios')->where('bid', $bid)->where('version_id', $version_id)
|
|
|
+ ->where('cid', $cid)->where('paragraph_audio_url', '!=', '')->select('sequence', 'paragraph_audio_url')
|
|
|
+ ->get()->map(function ($value) {
|
|
|
+ return (array)$value;
|
|
|
+ })->toArray();
|
|
|
+ if (count($paragraph_urls) != $tmp_url_count) {
|
|
|
+ $this->sendEvent([
|
|
|
+ 'code' => 0,
|
|
|
+ 'msg' => "",
|
|
|
+ 'data' => $paragraph_urls,
|
|
|
+ // 'message' => '数据更新',
|
|
|
+ // 'type' => 'update',
|
|
|
+ // 'timestamp' => date('H:i:s')
|
|
|
+ ]);
|
|
|
+ $tmp_url_count = count($paragraph_urls);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 等待1秒后发送下一条消息
|
|
|
+ sleep(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function sendEvent($data, $event = null, $id = null) {
|
|
|
+ // // 事件ID
|
|
|
+ // if ($id !== null) {
|
|
|
+ // echo "id: {$id}\n";
|
|
|
+ // }
|
|
|
+
|
|
|
+ // 事件类型
|
|
|
+ if ($event !== null) {
|
|
|
+ echo "event: {$event}\n";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 数据部分(JSON格式)
|
|
|
+ echo "data: " . json_encode($data) . "\n\n";
|
|
|
+
|
|
|
+ // 立即发送数据
|
|
|
+ if(ob_get_level()>0) ob_flush();
|
|
|
+ flush();
|
|
|
+ }
|
|
|
}
|