WebSocketService.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. namespace App\Services;
  3. use App\Module\Base;
  4. use Cache;
  5. use DB;
  6. use Hhxsv5\LaravelS\Swoole\WebSocketHandlerInterface;
  7. use Swoole\Http\Request;
  8. use Swoole\WebSocket\Frame;
  9. use Swoole\WebSocket\Server;
  10. /**
  11. * @see https://wiki.swoole.com/#/start/start_ws_server
  12. */
  13. class WebSocketService implements WebSocketHandlerInterface
  14. {
  15. /**
  16. * 声明没有参数的构造函数
  17. * WebSocketService constructor.
  18. */
  19. public function __construct()
  20. {
  21. }
  22. /**
  23. * 连接建立时触发
  24. * @param Server $server
  25. * @param Request $request
  26. */
  27. public function onOpen(Server $server, Request $request)
  28. {
  29. $to = $request->fd;
  30. if (!isset($request->get['token'])) {
  31. $server->push($to, Base::array2json([
  32. 'messageType' => 'error',
  33. 'type' => 'user',
  34. 'sender' => null,
  35. 'target' => null,
  36. 'content' => [
  37. 'error' => '参数错误'
  38. ],
  39. 'time' => Base::time()
  40. ]));
  41. $server->close($to);
  42. self::forgetUser($to);
  43. return;
  44. }
  45. //
  46. $token = $request->get['token'];
  47. $cacheKey = "ws-token:" . md5($token);
  48. $username = Cache::remember($cacheKey, now()->addSeconds(1), function () use ($token) {
  49. list($id, $username, $encrypt, $timestamp) = explode("@", base64_decode($token) . "@@@@");
  50. if (intval($id) > 0 && intval($timestamp) + 2592000 > Base::time()) {
  51. if (DB::table('users')->where(['id' => $id, 'username' => $username, 'encrypt' => $encrypt])->exists()) {
  52. return $username;
  53. }
  54. }
  55. return null;
  56. });
  57. if (empty($username)) {
  58. Cache::forget($cacheKey);
  59. $server->push($to, Base::array2json([
  60. 'messageType' => 'error',
  61. 'type' => 'user',
  62. 'sender' => null,
  63. 'target' => null,
  64. 'content' => [
  65. 'error' => '会员不存在',
  66. ],
  67. 'time' => Base::time()
  68. ]));
  69. $server->close($to);
  70. self::forgetUser($to);
  71. return;
  72. }
  73. //
  74. self::saveUser($to, $username);
  75. $server->push($to, Base::array2json([
  76. 'messageType' => 'open',
  77. 'type' => 'user',
  78. 'sender' => null,
  79. 'target' => null,
  80. 'content' => [
  81. 'swid' => $to,
  82. ],
  83. 'time' => Base::time()
  84. ]));
  85. }
  86. /**
  87. * 收到消息时触发
  88. * @param Server $server
  89. * @param Frame $frame
  90. */
  91. public function onMessage(Server $server, Frame $frame)
  92. {
  93. $data = Base::json2array($frame->data);
  94. switch ($data['type']) {
  95. case 'user':
  96. $to = self::name2fs($data['target']);
  97. if ($to) {
  98. $server->push($to, Base::array2json($data));
  99. }
  100. break;
  101. case 'all':
  102. foreach (self::getUsers() as $user) {
  103. $data['target'] = $user['username'];
  104. $server->push($user['wsid'], Base::array2json($data));
  105. }
  106. break;
  107. }
  108. }
  109. /**
  110. * 关闭连接时触发
  111. * @param Server $server
  112. * @param $fd
  113. * @param $reactorId
  114. */
  115. public function onClose(Server $server, $fd, $reactorId)
  116. {
  117. self::forgetUser($fd);
  118. }
  119. /** ****************************************************************************** */
  120. /** ****************************************************************************** */
  121. /** ****************************************************************************** */
  122. /**
  123. * 缓存用户信息
  124. * @param $fd
  125. * @param $username
  126. */
  127. public static function saveUser($fd, $username)
  128. {
  129. DB::table('users')->where('wsid', $fd)->update(['wsid' => 0]);
  130. DB::table('users')->where('username', $username)->update(['wsid' => $fd]);
  131. }
  132. /**
  133. * 清除用户缓存
  134. * @param $fd
  135. */
  136. public static function forgetUser($fd)
  137. {
  138. DB::table('users')->where('wsid', $fd)->update(['wsid' => 0]);
  139. }
  140. /**
  141. * 获取当前用户
  142. * @return array|string
  143. */
  144. public static function getUsers()
  145. {
  146. return Base::DBC2A(DB::table('users')->select(['wsid', 'username'])->where('wsid', '>', 0)->get());
  147. }
  148. /**
  149. * @param $fd
  150. * @return mixed
  151. */
  152. public static function fd2name($fd)
  153. {
  154. return DB::table('users')->select(['username'])->where('wsid', $fd)->value('username');
  155. }
  156. /**
  157. * @param $username
  158. * @return mixed
  159. */
  160. public static function name2fs($username)
  161. {
  162. return DB::table('users')->select(['wsid'])->where('username', $username)->value('wsid');
  163. }
  164. }