hyperf-chat/app/Controller/WebSocketController.php

104 lines
2.9 KiB
PHP
Raw Normal View History

2020-11-02 22:45:37 +08:00
<?php
declare(strict_types=1);
namespace App\Controller;
2020-11-07 22:57:10 +08:00
use Hyperf\Di\Annotation\Inject;
2020-11-02 22:45:37 +08:00
use Hyperf\Contract\OnCloseInterface;
use Hyperf\Contract\OnMessageInterface;
use Hyperf\Contract\OnOpenInterface;
2020-11-07 22:57:10 +08:00
use Hyperf\Utils\Codec\Json;
use Phper666\JWTAuth\JWT;
2020-11-02 22:45:37 +08:00
use Swoole\Http\Request;
use Swoole\Websocket\Frame;
2020-11-03 14:07:54 +08:00
use Hyperf\Amqp\Producer;
2020-11-04 11:57:16 +08:00
use App\Amqp\Producer\ChatMessageProducer;
2020-11-07 22:57:10 +08:00
use Swoole\Http\Response;
use Swoole\WebSocket\Server;
use App\Traits\WebSocketTrait;
use App\Service\SocketFDService;
2020-11-03 14:07:54 +08:00
2020-11-07 22:57:10 +08:00
/**
* Class WebSocketController
* @package App\Controller
*/
2020-11-02 22:45:37 +08:00
class WebSocketController implements OnMessageInterface, OnOpenInterface, OnCloseInterface
{
2020-11-07 22:57:10 +08:00
use WebSocketTrait;
/**
* @Inject
* @var JWT
*/
private $jwt;
/**
* @inject
* @var SocketFDService
*/
private $socketFDService;
/**
* 连接创建成功回调事件
*
* @param Response|Server $server
* @param Request $request
*/
public function onOpen($server, Request $request): void
2020-11-02 22:45:37 +08:00
{
2020-11-07 22:57:10 +08:00
$token = $request->get['token'] ?? '';
$userInfo = $this->jwt->getParserData($token);
2020-11-08 22:58:17 +08:00
stdout_log()->notice("用户连接信息 : user_id:{$userInfo['user_id']} | fd:{$request->fd} | data:" . Json::encode($userInfo));
2020-11-09 17:41:22 +08:00
stdout_log()->notice('连接时间:' . date('Y-m-d H:i:s'));
2020-11-07 22:57:10 +08:00
// 绑定fd与用户关系
$this->socketFDService->bindRelation($request->fd, $userInfo['user_id']);
2020-11-03 14:07:54 +08:00
2020-11-03 17:12:57 +08:00
$ip = config('ip_address');
2020-11-07 22:57:10 +08:00
$server->push($request->fd, "成功连接[{$ip}],IM 服务器");
2020-11-02 22:45:37 +08:00
}
2020-11-07 22:57:10 +08:00
/**
* 消息接收回调事件
*
* @param Response|Server $server
* @param Frame $frame
*/
public function onMessage($server, Frame $frame): void
2020-11-02 22:45:37 +08:00
{
2020-11-08 22:58:17 +08:00
// 判断是否为心跳检测
if ($frame->data == 'PING') return;
2020-11-07 22:57:10 +08:00
$ip = config('ip_address');
$producer = container()->get(Producer::class);
$producer->produce(new ChatMessageProducer("我是来自[{$ip} 服务器的消息]{$frame->data}"));
2020-11-02 22:45:37 +08:00
}
2020-11-07 22:57:10 +08:00
/**
* 连接创建成功回调事件
*
* @param Response|\Swoole\Server $server
* @param int $fd
* @param int $reactorId
*/
public function onClose($server, int $fd, int $reactorId): void
2020-11-02 22:45:37 +08:00
{
2020-11-08 22:58:17 +08:00
$user_id = $this->socketFDService->findFdUserId($fd);
stdout_log()->notice("客户端FD:{$fd} 已关闭连接,用户ID为【{$user_id}");
2020-11-09 17:41:22 +08:00
stdout_log()->notice('关闭时间:' . date('Y-m-d H:i:s'));
2020-11-08 22:58:17 +08:00
2020-11-07 22:57:10 +08:00
// 解除fd关系
$this->socketFDService->removeRelation($fd);
2020-11-08 22:58:17 +08:00
2020-11-09 17:41:22 +08:00
// 判断是否存在异地登录
$isOnline = $this->socketFDService->isOnlineAll(intval($user_id));
if (!$isOnline) {
// ... 不存在异地登录,推送下线通知消息
// ... 包装推送消息至队列
} else {
stdout_log()->notice("用户:{$user_id} 存在异地登录...");
}
2020-11-02 22:45:37 +08:00
}
}