eee
This commit is contained in:
@@ -22,6 +22,12 @@ class Struct
|
||||
|
||||
public Response $ws;
|
||||
|
||||
|
||||
/**
|
||||
* @param AuthorizationInterface $user
|
||||
* @param Request $request
|
||||
* @param Response $ws
|
||||
*/
|
||||
public function __construct(AuthorizationInterface $user, Request $request, Response $ws)
|
||||
{
|
||||
$this->user = $user;
|
||||
@@ -33,6 +39,10 @@ class Struct
|
||||
$this->lastSeenAt = $this->connectedAt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function touch(): void
|
||||
{
|
||||
$this->lastSeenAt = time();
|
||||
|
||||
@@ -14,6 +14,12 @@ class Transport
|
||||
*/
|
||||
private array $userIdByFd = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param Struct $data
|
||||
* @return Struct|null
|
||||
*/
|
||||
public function add(int $userId, Struct $data): ?Struct
|
||||
{
|
||||
$previous = $this->clients[$userId] ?? null;
|
||||
@@ -31,6 +37,12 @@ class Transport
|
||||
return $previous;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function sendUserId(int $userId, mixed $data): void
|
||||
{
|
||||
$struct = $this->clients[$userId] ?? null;
|
||||
@@ -42,6 +54,12 @@ class Transport
|
||||
@$struct->ws->push($this->normalizePayload($data));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $fd
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function sendFd(int $fd, mixed $data): void
|
||||
{
|
||||
$struct = $this->getClientId($fd);
|
||||
@@ -53,6 +71,11 @@ class Transport
|
||||
@$struct->ws->push($this->normalizePayload($data));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return void
|
||||
*/
|
||||
public function close(int $userId): void
|
||||
{
|
||||
$struct = $this->clients[$userId] ?? null;
|
||||
@@ -63,6 +86,12 @@ class Transport
|
||||
@$struct->ws->close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int|null $fd
|
||||
* @return void
|
||||
*/
|
||||
public function remove(int $userId, ?int $fd = null): void
|
||||
{
|
||||
$struct = $this->clients[$userId] ?? null;
|
||||
@@ -80,6 +109,11 @@ class Transport
|
||||
@$struct->ws->close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $fd
|
||||
* @return Struct|null
|
||||
*/
|
||||
public function getClientId(int $fd): ?Struct
|
||||
{
|
||||
$userId = $this->userIdByFd[$fd] ?? null;
|
||||
@@ -90,16 +124,31 @@ class Transport
|
||||
return $this->clients[$userId] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return Struct|null
|
||||
*/
|
||||
public function getUserId(int $userId): ?Struct
|
||||
{
|
||||
return $this->clients[$userId] ?? null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return bool
|
||||
*/
|
||||
public function has(int $userId): bool
|
||||
{
|
||||
return isset($this->clients[$userId]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @param int|null $fd
|
||||
* @return void
|
||||
*/
|
||||
public function touch(int $userId, ?int $fd = null): void
|
||||
{
|
||||
$struct = $this->clients[$userId] ?? null;
|
||||
@@ -114,6 +163,10 @@ class Transport
|
||||
$struct->touch();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLists(): array
|
||||
{
|
||||
$array = [];
|
||||
@@ -130,11 +183,20 @@ class Transport
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function size(): int
|
||||
{
|
||||
return count($this->clients);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $data
|
||||
* @return string
|
||||
*/
|
||||
private function normalizePayload(mixed $data): string
|
||||
{
|
||||
if (is_string($data)) {
|
||||
|
||||
+92
-7
@@ -2,8 +2,11 @@
|
||||
|
||||
namespace Coroutine\Server;
|
||||
|
||||
use Kiri\Di\Context;
|
||||
use Kiri\Di\Inject\Container;
|
||||
use Kiri\Router\Constrict\ConstrictRequest;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Coroutine\Http\Server;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
@@ -15,8 +18,17 @@ abstract class Websocket
|
||||
#[Container(Transport::class)]
|
||||
public Transport $transport;
|
||||
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
public Config $config;
|
||||
|
||||
|
||||
/**
|
||||
* @param Config $config
|
||||
* @return void
|
||||
*/
|
||||
public function start(Config $config): void
|
||||
{
|
||||
$this->config = $config;
|
||||
@@ -35,6 +47,12 @@ abstract class Websocket
|
||||
$server->start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $ws
|
||||
* @return void
|
||||
*/
|
||||
public function getLists(Request $request, Response $ws): void
|
||||
{
|
||||
try {
|
||||
@@ -59,6 +77,12 @@ abstract class Websocket
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $ws
|
||||
* @return void
|
||||
*/
|
||||
public function handler(Request $request, Response $ws): void
|
||||
{
|
||||
$upgraded = false;
|
||||
@@ -115,11 +139,21 @@ abstract class Websocket
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
abstract public function onBeforeMessageLoop(): void;
|
||||
|
||||
protected function authorizeConnection(Request $request): ConstrictRequest
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return ConstrictRequest
|
||||
*/
|
||||
protected function authorizeConnection(Request $request): RequestInterface
|
||||
{
|
||||
$psr7Request = ConstrictRequest::builder($request);
|
||||
/** @var RequestInterface $psr7Request */
|
||||
$psr7Request = Context::set(RequestInterface::class, ConstrictRequest::builder($request));
|
||||
if (!$psr7Request->hasQuery($this->config->authKey)) {
|
||||
throw new \RuntimeException('Missing auth parameter.', 400);
|
||||
}
|
||||
@@ -131,7 +165,12 @@ abstract class Websocket
|
||||
return $psr7Request;
|
||||
}
|
||||
|
||||
protected function authorizeOnlineListRequest(ConstrictRequest $request): bool
|
||||
|
||||
/**
|
||||
* @param ConstrictRequest $request
|
||||
* @return bool
|
||||
*/
|
||||
protected function authorizeOnlineListRequest(RequestInterface $request): bool
|
||||
{
|
||||
if (!$request->hasQuery($this->config->authKey)) {
|
||||
return false;
|
||||
@@ -140,20 +179,34 @@ abstract class Websocket
|
||||
return $this->canViewOnlineLists($request) && $request->getAuthority() !== null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ConstrictRequest $request
|
||||
* @return bool
|
||||
*/
|
||||
protected function canViewOnlineLists(ConstrictRequest $request): bool
|
||||
{
|
||||
return $this->onConnected($request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function configureRuntime(): void
|
||||
{
|
||||
if ($this->config->maxCoroutine > 0 && class_exists(\Swoole\Coroutine::class)) {
|
||||
\Swoole\Coroutine::set([
|
||||
if ($this->config->maxCoroutine > 0 && class_exists(Coroutine::class)) {
|
||||
Coroutine::set([
|
||||
'max_coroutine' => $this->config->maxCoroutine,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @return void
|
||||
*/
|
||||
private function configureServer(Server $server): void
|
||||
{
|
||||
if (!method_exists($server, 'set')) {
|
||||
@@ -173,6 +226,11 @@ abstract class Websocket
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $payload
|
||||
* @return void
|
||||
*/
|
||||
private function assertPayloadSize(string $payload): void
|
||||
{
|
||||
$size = strlen($payload);
|
||||
@@ -186,6 +244,13 @@ abstract class Websocket
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Response $ws
|
||||
* @param Throwable $throwable
|
||||
* @param bool $upgraded
|
||||
* @return void
|
||||
*/
|
||||
private function throwable(Response $ws, Throwable $throwable, bool $upgraded): void
|
||||
{
|
||||
$status = $throwable->getCode();
|
||||
@@ -220,11 +285,31 @@ abstract class Websocket
|
||||
$ws->end($message);
|
||||
}
|
||||
|
||||
abstract public function onConnected(ConstrictRequest $request): bool;
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function onConnected(RequestInterface $request): bool;
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
abstract public function onStart(): void;
|
||||
|
||||
abstract public function onMessage(ConstrictRequest $psr7Request, string $frame): void;
|
||||
|
||||
/**
|
||||
* @param RequestInterface $psr7Request
|
||||
* @param string $frame
|
||||
* @return void
|
||||
*/
|
||||
abstract public function onMessage(RequestInterface $psr7Request, string $frame): void;
|
||||
|
||||
|
||||
/**
|
||||
* @param int $userId
|
||||
* @return void
|
||||
*/
|
||||
abstract public function onDisconnect(int $userId): void;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use Coroutine\Server\Config;
|
||||
use Coroutine\Server\Websocket;
|
||||
use Kiri\Router\Constrict\ConstrictRequest;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use function Co\run;
|
||||
|
||||
|
||||
@@ -18,11 +19,11 @@ class Test extends Websocket
|
||||
* @param ConstrictRequest $request
|
||||
* @return bool
|
||||
*/
|
||||
public function onConnected(ConstrictRequest $request): bool
|
||||
public function onConnected(RequestInterface $request): bool
|
||||
{
|
||||
// TODO: Implement onConnected() method.
|
||||
|
||||
// $request->withAuthority($authorization);
|
||||
// $request->withAuthority(null);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -36,7 +37,7 @@ class Test extends Websocket
|
||||
* @param string $frame
|
||||
* @return void
|
||||
*/
|
||||
public function onMessage(ConstrictRequest $psr7Request, string $frame): void
|
||||
public function onMessage(RequestInterface $psr7Request, string $frame): void
|
||||
{
|
||||
// TODO: Implement onMessage() method.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user