Realtime.php 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. <?php
  2. namespace App\Http\Controllers\admin;
  3. use App\Constants\HttpStatus;
  4. use App\Http\Controllers\Controller;
  5. use App\Services\AdminRealtime\AdminRealtimeFeed;
  6. use App\Services\AdminRealtime\AdminRealtimeTicket;
  7. use App\Services\JwtService;
  8. use Exception;
  9. use Illuminate\Http\JsonResponse;
  10. /** 后台订单、用户列表实时推送,接入说明见 docs/admin-websocket.md */
  11. class Realtime extends Controller
  12. {
  13. /** 后台登录态换取推送网关连接票据 */
  14. public function ticket(JwtService $jwtService): JsonResponse
  15. {
  16. try {
  17. if (!config('admin_realtime.enabled')) {
  18. throw new Exception('实时推送未启用');
  19. }
  20. $token = str_replace('Bearer ', '', (string) request()->header('Authorization'));
  21. $session = $jwtService->validateToken($token);
  22. $result = AdminRealtimeTicket::issue((int) request()->user->id, isset($session->exp) ? (int) $session->exp : null);
  23. } catch (Exception $e) {
  24. return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
  25. }
  26. return $this->success($result);
  27. }
  28. /** 推送网关内部拉取事件,仅凭 X-Realtime-Secret 访问 */
  29. public function events(): JsonResponse
  30. {
  31. $secret = (string) config('admin_realtime.internal_secret');
  32. if ($secret === '' || !hash_equals($secret, (string) request()->header('X-Realtime-Secret'))) {
  33. return response()->json(['code' => HttpStatus::CUSTOM_ERROR, 'timestamp' => time(), 'msg' => 'forbidden', 'data' => []], 403);
  34. }
  35. if (!config('admin_realtime.enabled')) {
  36. return $this->error(HttpStatus::CUSTOM_ERROR, '实时推送未启用');
  37. }
  38. try {
  39. $gaps = array_filter(explode(',', (string) request()->input('gaps', '')), 'ctype_digit');
  40. $result = AdminRealtimeFeed::pull((int) request()->input('after', -1), $gaps);
  41. } catch (\Throwable $e) {
  42. return $this->error(HttpStatus::CUSTOM_ERROR, $e->getMessage());
  43. }
  44. return $this->success($result);
  45. }
  46. }