123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- <?php
- namespace App\Http\Controllers\DeepSeek;
- use App\Facade\Site;
- use App\Consts\ErrorConst;
- use App\Exceptions\ApiException;
- use App\Libs\ApiResponse;
- 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;
- class DeepSeekController extends BaseController
- {
- use ApiResponse;
- protected $deepseekService;
- public function __construct(
- DeepSeekService $deepseekService
- ) {
- $this->deepseekService = $deepseekService;
- }
- /**
- * 可选供应商
- *
- * @param Request $request
- * @return mixed
- */
- public function chatWithReasoner(Request $request) {
- // 忽略所有超时限制
- set_time_limit(0);
- ini_set('max_execution_time', '0');
- $data = $request->all();
- $result = $this->deepseekService->chatWithReasoner($data);
- return $this->success($result);
- }
- /**
- * 音色列表
- *
- * @param Request $request
- * @return mixed
- */
- public function timbreList(Request $request) {
- $data = $request->all();
- $result = $this->deepseekService->timbreList($data);
- return $this->success($result);
- }
- // 保存段落音频
- public function saveParagraphAudio(Request $request) {
- $data = $request->all();
- $result = $this->deepseekService->saveParagraphAudio($data);
- return $this->success(['success'=>$result ? 1 : 0]);
- }
- /**
- * 新增合成任务
- *
- * @param Request $request
- * @return mixed
- */
- public function addGenerateTask(Request $request) {
- $data = $request->all();
- $result = $this->deepseekService->addGenerateTask($data);
- return $this->success(['success'=>$result ? 1 : 0]);
- }
- // 获取火山临时token
- public function setStsToken(Request $request) {
- $data = $request->all();
- $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(function($query) {
- return $query->where('paragraph_audio_url', '!=', '')->orWhere('error_msg', '!=', '');
- })->select('sequence', 'paragraph_audio_url', 'error_msg')
- ->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();
- }
- }
|