modify
This commit is contained in:
@@ -1,34 +1,15 @@
|
||||
<?php
|
||||
|
||||
use SInterface\CustomProcess;
|
||||
use Swoole\Coroutine;
|
||||
namespace Server;
|
||||
|
||||
use Server\SInterface\CustomProcess;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Http\Server as HServer;
|
||||
use Swoole\Process;
|
||||
use Swoole\Server;
|
||||
use Swoole\WebSocket\Server as WServer;
|
||||
use Task\ServerTask;
|
||||
use Server\Task\ServerTask;
|
||||
|
||||
require_once 'HTTPServerListener.php';
|
||||
require_once 'TCPServerListener.php';
|
||||
require_once 'UDPServerListener.php';
|
||||
require_once 'WebSocketServerListener.php';
|
||||
require_once 'Task/ServerTask.php';
|
||||
require_once 'ListenerHelper.php';
|
||||
require_once 'Manager/ServerManager.php';
|
||||
require_once 'Manager/ServerBase.php';
|
||||
require_once 'Worker/ServerWorker.php';
|
||||
|
||||
|
||||
/**
|
||||
* @param Closure $closure
|
||||
* @param int $sleep
|
||||
*/
|
||||
function loop(Closure $closure, int $sleep = 1)
|
||||
{
|
||||
call_user_func($closure);
|
||||
|
||||
loop($closure, $sleep);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class BASEServerListener
|
||||
@@ -50,35 +31,6 @@ class BASEServerListener
|
||||
private static ?BASEServerListener $BASEServerListener = null;
|
||||
|
||||
|
||||
const SERVER_TYPE_HTTP = 'http';
|
||||
const SERVER_TYPE_WEBSOCKET = 'ws';
|
||||
const SERVER_TYPE_TCP = 'tcp';
|
||||
const SERVER_TYPE_UDP = 'udp';
|
||||
const SERVER_TYPE_BASE = 'base';
|
||||
|
||||
|
||||
const SERVER_ON_START = 'Start';
|
||||
const SERVER_ON_SHUTDOWN = 'Shutdown';
|
||||
const SERVER_ON_WORKER_START = 'WorkerStart';
|
||||
const SERVER_ON_WORKER_STOP = 'WorkerStop';
|
||||
const SERVER_ON_WORKER_EXIT = 'WorkerExit';
|
||||
const SERVER_ON_CONNECT = 'Connect';
|
||||
const SERVER_ON_HANDSHAKE = 'handshake';
|
||||
const SERVER_ON_MESSAGE = 'message';
|
||||
const SERVER_ON_RECEIVE = 'Receive';
|
||||
const SERVER_ON_PACKET = 'Packet';
|
||||
const SERVER_ON_REQUEST = 'request';
|
||||
const SERVER_ON_CLOSE = 'Close';
|
||||
const SERVER_ON_TASK = 'Task';
|
||||
const SERVER_ON_FINISH = 'Finish';
|
||||
const SERVER_ON_PIPE_MESSAGE = 'PipeMessage';
|
||||
const SERVER_ON_WORKER_ERROR = 'WorkerError';
|
||||
const SERVER_ON_MANAGER_START = 'ManagerStart';
|
||||
const SERVER_ON_MANAGER_STOP = 'ManagerStop';
|
||||
const SERVER_ON_BEFORE_RELOAD = 'BeforeReload';
|
||||
const SERVER_ON_AFTER_RELOAD = 'AfterReload';
|
||||
|
||||
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
@@ -131,7 +83,6 @@ class BASEServerListener
|
||||
foreach ($this->sortService($configs['server']['ports']) as $config) {
|
||||
$this->startListenerHandler($context, $config);
|
||||
}
|
||||
$this->addProcess(RelationshipSystemProcess::class);
|
||||
$this->addServerEventCallback($this->getSystemEvents($configs));
|
||||
$context->server->start();
|
||||
}
|
||||
@@ -169,10 +120,10 @@ class BASEServerListener
|
||||
{
|
||||
$array = [];
|
||||
foreach ($ports as $port) {
|
||||
if ($port['type'] == static::SERVER_TYPE_WEBSOCKET) {
|
||||
if ($port['type'] == Constant::SERVER_TYPE_WEBSOCKET) {
|
||||
array_unshift($array, $port);
|
||||
} else if ($port['type'] == static::SERVER_TYPE_HTTP) {
|
||||
if (!empty($array) && $array[0]['type'] == self::SERVER_TYPE_WEBSOCKET) {
|
||||
} else if ($port['type'] == Constant::SERVER_TYPE_HTTP) {
|
||||
if (!empty($array) && $array[0]['type'] == Constant::SERVER_TYPE_WEBSOCKET) {
|
||||
$array[] = $port;
|
||||
} else {
|
||||
array_unshift($array, $port);
|
||||
@@ -192,17 +143,17 @@ class BASEServerListener
|
||||
private function getSystemEvents(array $configs): array
|
||||
{
|
||||
return array_intersect_key($configs['server']['events'] ?? [], [
|
||||
BASEServerListener::SERVER_ON_PIPE_MESSAGE => '',
|
||||
BASEServerListener::SERVER_ON_SHUTDOWN => '',
|
||||
BASEServerListener::SERVER_ON_WORKER_START => '',
|
||||
BASEServerListener::SERVER_ON_WORKER_ERROR => '',
|
||||
BASEServerListener::SERVER_ON_WORKER_EXIT => '',
|
||||
BASEServerListener::SERVER_ON_WORKER_STOP => '',
|
||||
BASEServerListener::SERVER_ON_MANAGER_START => '',
|
||||
BASEServerListener::SERVER_ON_MANAGER_STOP => '',
|
||||
BASEServerListener::SERVER_ON_BEFORE_RELOAD => '',
|
||||
BASEServerListener::SERVER_ON_AFTER_RELOAD => '',
|
||||
BASEServerListener::SERVER_ON_START => '',
|
||||
Constant::PIPE_MESSAGE => '',
|
||||
Constant::SHUTDOWN => '',
|
||||
Constant::WORKER_START => '',
|
||||
Constant::WORKER_ERROR => '',
|
||||
Constant::WORKER_EXIT => '',
|
||||
Constant::WORKER_STOP => '',
|
||||
Constant::MANAGER_START => '',
|
||||
Constant::MANAGER_STOP => '',
|
||||
Constant::BEFORE_RELOAD => '',
|
||||
Constant::AFTER_RELOAD => '',
|
||||
Constant::START => '',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -235,16 +186,16 @@ class BASEServerListener
|
||||
private function addNewListener(string $type, string $host, int $port, int $mode, array $settings = [])
|
||||
{
|
||||
switch ($type) {
|
||||
case self::SERVER_TYPE_TCP:
|
||||
case Constant::SERVER_TYPE_TCP:
|
||||
TCPServerListener::instance($this->server, $host, $port, $mode, $settings);
|
||||
break;
|
||||
case self::SERVER_TYPE_UDP:
|
||||
case Constant::SERVER_TYPE_UDP:
|
||||
UDPServerListener::instance($this->server, $host, $port, $mode, $settings);
|
||||
break;
|
||||
case self::SERVER_TYPE_HTTP:
|
||||
case Constant::SERVER_TYPE_HTTP:
|
||||
HTTPServerListener::instance($this->server, $host, $port, $mode, $settings);
|
||||
break;
|
||||
case self::SERVER_TYPE_WEBSOCKET:
|
||||
case Constant::SERVER_TYPE_WEBSOCKET:
|
||||
WebSocketServerListener::instance($this->server, $host, $port, $mode, $settings);
|
||||
break;
|
||||
}
|
||||
@@ -261,9 +212,11 @@ class BASEServerListener
|
||||
private function createBaseServer(string $type, string $host, int $port, int $mode, array $settings = [])
|
||||
{
|
||||
$match = match ($type) {
|
||||
self::SERVER_TYPE_BASE, self::SERVER_TYPE_TCP, self::SERVER_TYPE_UDP => Server::class,
|
||||
self::SERVER_TYPE_HTTP => HServer::class,
|
||||
self::SERVER_TYPE_WEBSOCKET => WServer::class
|
||||
Constant::SERVER_TYPE_BASE,
|
||||
Constant::SERVER_TYPE_TCP,
|
||||
Constant::SERVER_TYPE_UDP => Server::class,
|
||||
Constant::SERVER_TYPE_HTTP => HServer::class,
|
||||
Constant::SERVER_TYPE_WEBSOCKET => WServer::class
|
||||
};
|
||||
$this->server = new $match($host, $port, SWOOLE_PROCESS, $mode);
|
||||
$this->server->set($settings['settings']);
|
||||
@@ -279,16 +232,20 @@ class BASEServerListener
|
||||
private function addDefaultListener(string $type, array $settings): void
|
||||
{
|
||||
if (($this->server->setting['task_worker_num'] ?? 0) > 0) $this->addTaskListener($settings['events']);
|
||||
if ($type === BASEServerListener::SERVER_TYPE_WEBSOCKET) {
|
||||
$this->server->on('handshake', $settings['events'][static::SERVER_ON_HANDSHAKE] ?? [WebSocketServerListener::class, 'onHandshake']);
|
||||
$this->server->on('message', $settings['events'][static::SERVER_ON_MESSAGE] ?? [WebSocketServerListener::class, 'onMessage']);
|
||||
$this->server->on('close', $settings['events'][static::SERVER_ON_CLOSE] ?? [WebSocketServerListener::class, 'onClose']);
|
||||
} else if ($type === BASEServerListener::SERVER_TYPE_UDP) {
|
||||
$this->server->on('packet', $settings['events'][static::SERVER_ON_PACKET] ?? [UDPServerListener::class, 'onPacket']);
|
||||
} else if ($type === BASEServerListener::SERVER_TYPE_HTTP) {
|
||||
$this->server->on('request', $settings['events'][static::SERVER_ON_REQUEST] ?? [HTTPServerListener::class, 'onRequest']);
|
||||
if ($type === Constant::SERVER_TYPE_WEBSOCKET) {
|
||||
$reflect = Snowflake::getDi()->getReflect(WebSocketServerListener::class)?->newInstance();
|
||||
$this->server->on('handshake', $settings['events'][Constant::HANDSHAKE] ?? [$reflect, 'onHandshake']);
|
||||
$this->server->on('message', $settings['events'][Constant::MESSAGE] ?? [$reflect, 'onMessage']);
|
||||
$this->server->on('close', $settings['events'][Constant::CLOSE] ?? [$reflect, 'onClose']);
|
||||
} else if ($type === Constant::SERVER_TYPE_UDP) {
|
||||
$reflect = Snowflake::getDi()->getReflect(UDPServerListener::class)?->newInstance();
|
||||
$this->server->on('packet', $settings['events'][Constant::PACKET] ?? [$reflect, 'onPacket']);
|
||||
} else if ($type === Constant::SERVER_TYPE_HTTP) {
|
||||
$reflect = Snowflake::getDi()->getReflect(HTTPServerListener::class)?->newInstance();
|
||||
$this->server->on('request', $settings['events'][Constant::REQUEST] ?? [$reflect, 'onRequest']);
|
||||
} else {
|
||||
$this->server->on('receive', $settings['events'][static::SERVER_ON_RECEIVE] ?? [TCPServerListener::class, 'onReceive']);
|
||||
$reflect = Snowflake::getDi()->getReflect(TCPServerListener::class)?->newInstance();
|
||||
$this->server->on('receive', $settings['events'][Constant::RECEIVE] ?? [$reflect, 'onReceive']);
|
||||
}
|
||||
$this->addServerEventCallback($settings['events']);
|
||||
}
|
||||
@@ -317,12 +274,13 @@ class BASEServerListener
|
||||
private function addTaskListener(array $events = []): void
|
||||
{
|
||||
$task_use_object = $this->server->setting['task_object'] ?? $this->server->setting['task_use_object'] ?? false;
|
||||
$reflect = Snowflake::getDi()->getReflect(ServerTask::class)?->newInstance();
|
||||
if ($task_use_object || $this->server->setting['task_enable_coroutine']) {
|
||||
$this->server->on('task', $events[static::SERVER_ON_TASK] ?? [ServerTask::class, 'onCoroutineTask']);
|
||||
$this->server->on('task', $events[Constant::TASK] ?? [$reflect, 'onCoroutineTask']);
|
||||
} else {
|
||||
$this->server->on('task', $events[static::SERVER_ON_TASK] ?? [ServerTask::class, 'onTask']);
|
||||
$this->server->on('task', $events[Constant::TASK] ?? [$reflect, 'onTask']);
|
||||
}
|
||||
$this->server->on('finish', $events[static::SERVER_ON_FINISH] ?? [ServerTask::class, 'onFinish']);
|
||||
$this->server->on('finish', $events[Constant::FINISH] ?? [$reflect, 'onFinish']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Server;
|
||||
|
||||
|
||||
class Constant
|
||||
{
|
||||
|
||||
const START = 'Start';
|
||||
const SHUTDOWN = 'Shutdown';
|
||||
const WORKER_START = 'WorkerStart';
|
||||
const WORKER_STOP = 'WorkerStop';
|
||||
const WORKER_EXIT = 'WorkerExit';
|
||||
const CONNECT = 'Connect';
|
||||
const HANDSHAKE = 'handshake';
|
||||
const MESSAGE = 'message';
|
||||
const RECEIVE = 'Receive';
|
||||
const PACKET = 'Packet';
|
||||
const REQUEST = 'request';
|
||||
const CLOSE = 'Close';
|
||||
const TASK = 'Task';
|
||||
const FINISH = 'Finish';
|
||||
const PIPE_MESSAGE = 'PipeMessage';
|
||||
const WORKER_ERROR = 'WorkerError';
|
||||
const MANAGER_START = 'ManagerStart';
|
||||
const MANAGER_STOP = 'ManagerStop';
|
||||
const BEFORE_RELOAD = 'BeforeReload';
|
||||
const AFTER_RELOAD = 'AfterReload';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const SERVER_TYPE_HTTP = 'http';
|
||||
const SERVER_TYPE_WEBSOCKET = 'ws';
|
||||
const SERVER_TYPE_TCP = 'tcp';
|
||||
const SERVER_TYPE_UDP = 'udp';
|
||||
const SERVER_TYPE_BASE = 'base';
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
use HttpServer\Route\Router;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
|
||||
class HTTPServerListener
|
||||
{
|
||||
|
||||
protected static mixed $_http;
|
||||
|
||||
use ListenerHelper;
|
||||
|
||||
private Router $router;
|
||||
|
||||
/**
|
||||
* UDPServerListener constructor.
|
||||
* @param Server|\Swoole\WebSocket\Server|\Swoole\Http\Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function instance(mixed $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_TCP, SWOOLE_TCP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is udp listener type.');
|
||||
}
|
||||
$reflect = Snowflake::getDi()->getReflect(static::class)?->newInstance();
|
||||
static::$_http = $server->addlistener($host, $port, $mode);
|
||||
static::$_http->set($settings['settings'] ?? []);
|
||||
static::$_http->on('request', self::callback(Constant::REQUEST, $settings['events'], [$reflect, 'onRequest']));
|
||||
static::$_http->on('connect', static::callback(Constant::CONNECT, $settings['events'], [$reflect, 'onConnect']));
|
||||
static::$_http->on('close', static::callback(Constant::CLOSE, $settings['events'], [$reflect, 'onClose']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onConnect(Server $server, int $fd)
|
||||
{
|
||||
$server->confirm($fd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
*/
|
||||
public function onRequest(Request $request, Response $response)
|
||||
{
|
||||
if (!$response->isWritable()) {
|
||||
return;
|
||||
}
|
||||
$response->status(200);
|
||||
$response->end('');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onClose(Server $server, int $fd)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
trait ListenerHelper
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $server
|
||||
* @param $newServer
|
||||
*/
|
||||
public static function onConnectAndClose($settings, $newServer)
|
||||
{
|
||||
$reflect = Snowflake::getDi()->getReflect(static::class)?->newInstance();
|
||||
|
||||
$newServer->on('connect', static::callback(Constant::CONNECT, $settings['events'], [$reflect, 'onConnect']));
|
||||
$newServer->on('close', static::callback(Constant::CLOSE, $settings['events'], [$reflect, 'onClose']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $events
|
||||
* @param array|\Closure $default
|
||||
* @return array|\Closure|mixed
|
||||
* @throws \ReflectionException
|
||||
* @throws \Snowflake\Exception\NotFindClassException
|
||||
*/
|
||||
protected static function callback(string $name, array $events, array|\Closure $default)
|
||||
{
|
||||
if (!is_array($events) || !isset($events[$name])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$callback = $events[$name];
|
||||
if ($callback instanceof \Closure) {
|
||||
return $callback;
|
||||
}
|
||||
$object = Snowflake::getDi()->getReflect($callback[0]);
|
||||
if ($object->getMethod($callback[1])->isStatic()) {
|
||||
return $callback;
|
||||
}
|
||||
return [$object->newInstance(), $callback[1]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Manager;
|
||||
|
||||
class ServerBase
|
||||
{
|
||||
|
||||
|
||||
public function onStart()
|
||||
{
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
|
||||
public function onShutdown()
|
||||
{
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
|
||||
public function onPipeMessage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function onBeforeReload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function onAfterReload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Manager;
|
||||
|
||||
class ServerManager
|
||||
{
|
||||
|
||||
|
||||
public function onManagerStart()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function onManagerStop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Server\Protocol;
|
||||
|
||||
|
||||
abstract class Protocol
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return array
|
||||
*/
|
||||
public function resolveProtocol($data)
|
||||
{
|
||||
$explode = explode("\r\n\r\n", $data);
|
||||
|
||||
$http_protocol = [];
|
||||
foreach (explode("\r\n", $explode[0]) as $key => $datum) {
|
||||
if (empty($datum) || $key == 0) {
|
||||
continue;
|
||||
}
|
||||
[$key, $value] = explode(': ', $datum);
|
||||
|
||||
$http_protocol[trim($key)] = trim($value);
|
||||
}
|
||||
return [$http_protocol, $explode[1]];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Protocol;
|
||||
|
||||
|
||||
class WebSocket extends Protocol
|
||||
{
|
||||
|
||||
|
||||
//
|
||||
public function decode($received): ?string
|
||||
{
|
||||
$decoded = null;
|
||||
$buffer = $received;
|
||||
$len = ord($buffer[1]) & 127;
|
||||
if ($len === 126) {
|
||||
$masks = substr($buffer, 4, 4);
|
||||
$data = substr($buffer, 8);
|
||||
} else {
|
||||
if ($len === 127) {
|
||||
$masks = substr($buffer, 10, 4);
|
||||
$data = substr($buffer, 14);
|
||||
} else {
|
||||
$masks = substr($buffer, 2, 4);
|
||||
$data = substr($buffer, 6);
|
||||
}
|
||||
}
|
||||
for ($index = 0; $index < strlen($data); $index++) {
|
||||
$decoded .= $data[$index] ^ $masks[$index % 4];
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
const BINARY_TYPE_BLOB = "\x81";
|
||||
|
||||
|
||||
public function encode($buffer): string
|
||||
{
|
||||
$len = strlen($buffer);
|
||||
|
||||
$first_byte = self::BINARY_TYPE_BLOB;
|
||||
|
||||
if ($len <= 125) {
|
||||
$encode_buffer = $first_byte . chr($len) . $buffer;
|
||||
} else {
|
||||
if ($len <= 65535) {
|
||||
$encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer;
|
||||
} else {
|
||||
//pack("xxxN", $len)pack函数只处理2的32次方大小的文件,实际上2的32次方已经4G了。
|
||||
$encode_buffer = $first_byte . chr(127) . pack("xxxxN", $len) . $buffer;
|
||||
}
|
||||
}
|
||||
|
||||
return $encode_buffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $server
|
||||
* @param $fd
|
||||
* @param $data
|
||||
*/
|
||||
private function getWebSocketProtocol($data)
|
||||
{
|
||||
[$http_protocol, $body] = $this->resolveProtocol($data);
|
||||
$key = base64_encode(sha1($http_protocol['Sec-WebSocket-Key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
|
||||
$headers = [
|
||||
'HTTP/1.1 101 Switching Protocols',
|
||||
'Upgrade: websocket',
|
||||
'Connection: Upgrade',
|
||||
'Sec-WebSocket-Accept: ' . $key,
|
||||
'Sec-WebSocket-Version: 13',
|
||||
];
|
||||
if (isset($http_protocol['Sec-WebSocket-Protocol'])) {
|
||||
$headers[] = 'Sec-WebSocket-Protocol: ' . $http_protocol['Sec-WebSocket-Protocol'];
|
||||
}
|
||||
return implode("\r\n", $headers) . "\r\n\r\n";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace SInterface;
|
||||
namespace Server\SInterface;
|
||||
|
||||
|
||||
use Swoole\Process;
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace SInterface;
|
||||
namespace Server\SInterface;
|
||||
|
||||
|
||||
use Swoole\Server;
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
use HttpServer\Route\Router;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
* Class TCPServerListener
|
||||
* @package HttpServer\Service
|
||||
*/
|
||||
class TCPServerListener
|
||||
{
|
||||
|
||||
use ListenerHelper;
|
||||
|
||||
protected static mixed $_tcp;
|
||||
|
||||
|
||||
/**
|
||||
* UDPServerListener constructor.
|
||||
* @param Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function instance(Server $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_TCP, SWOOLE_TCP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is tcp listener type.');
|
||||
}
|
||||
$reflect = Snowflake::getDi()->getReflect(static::class)?->newInstance();
|
||||
static::$_tcp = $server->addlistener($host, $port, $mode);
|
||||
static::$_tcp->set($settings['settings'] ?? []);
|
||||
static::$_tcp->on('receive', self::callback(Constant::RECEIVE, $settings['events'], [$reflect, 'onReceive']));
|
||||
static::$_tcp->on('connect', static::callback(Constant::CONNECT, $settings['events'], [$reflect, 'onConnect']));
|
||||
static::$_tcp->on('close', static::callback(Constant::CLOSE, $settings['events'], [$reflect, 'onClose']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onConnect(Server $server, int $fd)
|
||||
{
|
||||
var_dump(__FILE__ . ':' . __LINE__);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
* @param int $reactor_id
|
||||
* @param string $data
|
||||
*/
|
||||
public function onReceive(Server $server, int $fd, int $reactor_id, string $data)
|
||||
{
|
||||
var_dump($data);
|
||||
$server->send($fd, $data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onClose(Server $server, int $fd)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Server\Task;
|
||||
|
||||
|
||||
use Server\SInterface\TaskExecute;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Server;
|
||||
|
||||
class ServerTask
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $task_id
|
||||
* @param int $src_worker_id
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function onTask(Server $server, int $task_id, int $src_worker_id, mixed $data)
|
||||
{
|
||||
try {
|
||||
$data = $this->resolve($data);
|
||||
} catch (\Throwable $exception) {
|
||||
$data = [$exception->getMessage()];
|
||||
} finally {
|
||||
$server->finish($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param Server\Task $task
|
||||
*/
|
||||
public function onCoroutineTask(Server $server, Server\Task $task)
|
||||
{
|
||||
try {
|
||||
$data = $this->resolve($task->data);
|
||||
} catch (\Throwable $exception) {
|
||||
$data = [$exception->getMessage()];
|
||||
} finally {
|
||||
$server->finish($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return null
|
||||
* @throws \ReflectionException
|
||||
* @throws \Snowflake\Exception\NotFindClassException
|
||||
*/
|
||||
private function resolve($data)
|
||||
{
|
||||
[$class, $params] = json_encode($data, true);
|
||||
|
||||
$reflect = Snowflake::getDi()->getReflect($class);
|
||||
|
||||
if (!$reflect->isInstantiable()) {
|
||||
return null;
|
||||
}
|
||||
$class = $reflect->newInstanceArgs($params);
|
||||
return $class->execute();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $task_id
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function onFinish(Server $server, int $task_id, mixed $data)
|
||||
{
|
||||
if (!($data instanceof TaskExecute)) {
|
||||
return;
|
||||
}
|
||||
$data->finish($server, $task_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
* Class UDPServerListener
|
||||
* @package HttpServer\Service
|
||||
*/
|
||||
class UDPServerListener
|
||||
{
|
||||
|
||||
protected static mixed $_udp;
|
||||
|
||||
|
||||
use ListenerHelper;
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
*/
|
||||
public static function instance(Server $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_UDP, SWOOLE_UDP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is udp listener type.');
|
||||
}
|
||||
static::$_udp = $server->addlistener($host, $port, $mode);
|
||||
static::$_udp->set($settings['settings'] ?? []);
|
||||
static::$_udp->on('packet', static::callback(Constant::PACKET, $settings['events'], [new static(), 'onPacket']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $data
|
||||
* @param array $clientInfo
|
||||
*/
|
||||
public function onPacket(Server $server, string $data, array $clientInfo)
|
||||
{
|
||||
$server->sendto($clientInfo['address'], $clientInfo['port'], $data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Server;
|
||||
|
||||
use Exception;
|
||||
use Snowflake\Snowflake;
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
use Swoole\WebSocket\Frame;
|
||||
|
||||
|
||||
/**
|
||||
* Class WebSocketServerListener
|
||||
* @package HttpServer\Service
|
||||
*/
|
||||
class WebSocketServerListener
|
||||
{
|
||||
|
||||
protected static Server\Port $_http;
|
||||
|
||||
use ListenerHelper;
|
||||
|
||||
/**
|
||||
* UDPServerListener constructor.
|
||||
* @param Server|\Swoole\WebSocket\Server|\Swoole\Http\Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
*/
|
||||
public static function instance(mixed $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_TCP, SWOOLE_TCP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is udp listener type.');
|
||||
}
|
||||
static::$_http = $server->addlistener($host, $port, $mode);
|
||||
static::$_http->set($settings['settings'] ?? []);
|
||||
static::$_http->on('connect', static::callback(Constant::CONNECT, $settings['events'], [new static(), 'onConnect']));
|
||||
static::$_http->on('handshake', static::callback(Constant::HANDSHAKE, $settings['events'], [new static(), 'onHandshake']));
|
||||
static::$_http->on('message', static::callback(Constant::MESSAGE, $settings['events'], [new static(), 'onMessage']));
|
||||
static::$_http->on('close', static::callback(Constant::CLOSE, $settings['events'], [new static(), 'onClose']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @throws Exception
|
||||
*/
|
||||
public function onHandshake(Request $request, Response $response)
|
||||
{
|
||||
/** @var \Swoole\WebSocket\Server $server */
|
||||
$secWebSocketKey = $request->header['sec-websocket-key'];
|
||||
$patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
|
||||
if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
|
||||
throw new Exception('protocol error.', 500);
|
||||
}
|
||||
$key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
|
||||
$headers = [
|
||||
'Upgrade' => 'websocket',
|
||||
'Connection' => 'Upgrade',
|
||||
'Sec-websocket-Accept' => $key,
|
||||
'Sec-websocket-Version' => '13',
|
||||
];
|
||||
if (isset($request->header['sec-websocket-protocol'])) {
|
||||
$headers['Sec-websocket-Protocol'] = $request->header['sec-websocket-protocol'];
|
||||
}
|
||||
foreach ($headers as $key => $val) {
|
||||
$response->setHeader($key, $val);
|
||||
}
|
||||
$response->setStatusCode(101);
|
||||
$response->end();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onConnect(Server $server, int $fd)
|
||||
{
|
||||
var_dump(__FILE__ . ':' . __LINE__);
|
||||
$server->confirm($fd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\WebSocket\Server|Server $server
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public function onMessage(\Swoole\WebSocket\Server|Server $server, Frame $frame)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public function onClose(Server $server, int $fd)
|
||||
{
|
||||
var_dump($server->getClientInfo($fd));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Server\Worker;
|
||||
|
||||
use Swoole\Server;
|
||||
|
||||
@@ -11,7 +12,7 @@ class ServerWorker
|
||||
* @param Server $server
|
||||
* @param int $workerId
|
||||
*/
|
||||
public static function onWorkerStart(Server $server, int $workerId)
|
||||
public function onWorkerStart(Server $server, int $workerId)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -21,7 +22,7 @@ class ServerWorker
|
||||
* @param Server $server
|
||||
* @param int $workerId
|
||||
*/
|
||||
public static function onWorkerStop(Server $server, int $workerId)
|
||||
public function onWorkerStop(Server $server, int $workerId)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -31,7 +32,7 @@ class ServerWorker
|
||||
* @param Server $server
|
||||
* @param int $workerId
|
||||
*/
|
||||
public static function onWorkerExit(Server $server, int $workerId)
|
||||
public function onWorkerExit(Server $server, int $workerId)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -44,7 +45,7 @@ class ServerWorker
|
||||
* @param int $exit_code
|
||||
* @param int $signal
|
||||
*/
|
||||
public static function onWorkerError(Server $server, int $worker_id, int $worker_pid, int $exit_code, int $signal)
|
||||
public function onWorkerError(Server $server, int $worker_id, int $worker_pid, int $exit_code, int $signal)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
|
||||
use Server\Constant;
|
||||
use Server\HTTPServerListener;
|
||||
use Server\Manager\ServerBase;
|
||||
use Server\Manager\ServerManager;
|
||||
use Server\TCPServerListener;
|
||||
use Server\UDPServerListener;
|
||||
use Server\WebSocketServerListener;
|
||||
use Server\Worker\ServerWorker;
|
||||
|
||||
return [
|
||||
'server' => [
|
||||
'settings' => [
|
||||
'worker_num' => swoole_cpu_num(),
|
||||
'reactor_num' => swoole_cpu_num(),
|
||||
'dispatch_mode' => 3,
|
||||
'task_worker_num' => 1,
|
||||
'enable_coroutine' => true,
|
||||
'task_enable_coroutine' => true,
|
||||
'daemonize' => 0,
|
||||
'open_tcp_keepalive' => 1,
|
||||
'heartbeat_check_interval' => 60,
|
||||
'heartbeat_idle_time' => 600,
|
||||
'tcp_keepidle' => 3,
|
||||
'tcp_keepinterval' => 1,
|
||||
'tcp_keepcount' => 2,
|
||||
'max_wait_time' => 60,
|
||||
'reload_async' => true,
|
||||
'enable_delay_receive' => true,
|
||||
'tcp_fastopen' => 1,
|
||||
'tcp_defer_accept' => 1
|
||||
],
|
||||
'events' => [
|
||||
Constant::PIPE_MESSAGE => [ServerBase::class, 'onPipeMessage'],
|
||||
Constant::SHUTDOWN => [ServerBase::class, 'onShutdown'],
|
||||
Constant::WORKER_START => [ServerWorker::class, 'onWorkerStart'],
|
||||
Constant::WORKER_ERROR => [ServerWorker::class, 'onWorkerError'],
|
||||
Constant::WORKER_EXIT => [ServerWorker::class, 'onWorkerExit'],
|
||||
Constant::WORKER_STOP => [ServerWorker::class, 'onWorkerStop'],
|
||||
Constant::MANAGER_START => [ServerManager::class, 'onManagerStart'],
|
||||
Constant::MANAGER_STOP => [ServerManager::class, 'onManagerStop'],
|
||||
Constant::BEFORE_RELOAD => [ServerBase::class, 'onBeforeReload'],
|
||||
Constant::AFTER_RELOAD => [ServerBase::class, 'onAfterReload'],
|
||||
Constant::START => [ServerBase::class, 'onStart'],
|
||||
],
|
||||
'ports' => [
|
||||
[
|
||||
'type' => Constant::SERVER_TYPE_HTTP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9002,
|
||||
'mode' => SWOOLE_SOCK_TCP,
|
||||
'events' => [
|
||||
Constant::REQUEST => [HTTPServerListener::class, 'onRequest'],
|
||||
],
|
||||
'settings' => [
|
||||
'open_http_protocol' => true,
|
||||
'open_http2_protocol' => false,
|
||||
'http_parse_cookie' => true,
|
||||
'http_compression' => true,
|
||||
'http_compression_level' => 5,
|
||||
'enable_unsafe_event' => false,
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => Constant::SERVER_TYPE_WEBSOCKET,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9001,
|
||||
'mode' => SWOOLE_SOCK_TCP,
|
||||
'settings' => [
|
||||
'open_http_protocol' => false,
|
||||
'open_http2_protocol' => false
|
||||
],
|
||||
'events' => [
|
||||
Constant::CONNECT => [WebSocketServerListener::class, 'onConnect'],
|
||||
Constant::HANDSHAKE => [WebSocketServerListener::class, 'onHandshake'],
|
||||
Constant::MESSAGE => [WebSocketServerListener::class, 'onMessage'],
|
||||
Constant::CLOSE => [WebSocketServerListener::class, 'onClose'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => Constant::SERVER_TYPE_TCP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9003,
|
||||
'mode' => SWOOLE_SOCK_TCP,
|
||||
'events' => [
|
||||
Constant::CONNECT => [TCPServerListener::class, 'onConnect'],
|
||||
Constant::RECEIVE => [TCPServerListener::class, 'onReceive'],
|
||||
Constant::CLOSE => [TCPServerListener::class, 'onClose'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => Constant::SERVER_TYPE_UDP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9004,
|
||||
'mode' => SWOOLE_SOCK_UDP,
|
||||
'events' => [
|
||||
Constant::PACKET => [UDPServerListener::class, 'onPacket'],
|
||||
]
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -36,6 +36,7 @@
|
||||
"psr-4": {
|
||||
"Snowflake\\": "System/",
|
||||
"HttpServer\\": "HttpServer/",
|
||||
"Server\\": "Server/",
|
||||
"validator\\": "Validator/",
|
||||
"Console\\": "Console/",
|
||||
"Database\\": "Database/",
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once 'ListenerHelper.php';
|
||||
require_once 'Router.php';
|
||||
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
|
||||
class HTTPServerListener
|
||||
{
|
||||
|
||||
protected static mixed $_http;
|
||||
|
||||
use ListenerHelper;
|
||||
|
||||
|
||||
/**
|
||||
* UDPServerListener constructor.
|
||||
* @param Server|\Swoole\WebSocket\Server|\Swoole\Http\Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
*/
|
||||
public static function instance(mixed $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_TCP, SWOOLE_TCP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is udp listener type.');
|
||||
}
|
||||
static::$_http = $server->addlistener($host, $port, $mode);
|
||||
static::$_http->set($settings['settings'] ?? []);
|
||||
static::$_http->on('request', $settings['events'][BASEServerListener::SERVER_ON_REQUEST] ?? [static::class, 'onRequest']);
|
||||
static::onConnectAndClose($server, static::$_http);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public static function onConnect(Server $server, int $fd)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
*/
|
||||
public static function onRequest(Request $request, Response $response)
|
||||
{
|
||||
$controller = Router::findPath($request->server['request_uri']);
|
||||
if (empty($controller)) {
|
||||
$response->status(404);
|
||||
} else {
|
||||
$response->status(200);
|
||||
}
|
||||
if (!$response->isWritable()) {
|
||||
return;
|
||||
}
|
||||
$response->end('');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public static function onClose(Server $server, int $fd)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
trait ListenerHelper
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param $server
|
||||
* @param $newServer
|
||||
*/
|
||||
public static function onConnectAndClose($server, $newServer)
|
||||
{
|
||||
// if (in_array($server->setting['dispatch_mode'] ?? 2, [1, 3])){
|
||||
// return;
|
||||
// }
|
||||
// if (!($server->setting['enable_unsafe_event'] ?? false)) {
|
||||
// return;
|
||||
// }
|
||||
$newServer->on('connect', $settings['events'][BASEServerListener::SERVER_ON_CONNECT] ?? [static::class, 'onConnect']);
|
||||
$newServer->on('close', $settings['events'][BASEServerListener::SERVER_ON_CLOSE] ?? [static::class, 'onClose']);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
class ServerBase
|
||||
{
|
||||
|
||||
|
||||
public static function onStart()
|
||||
{
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
|
||||
public static function onShutdown()
|
||||
{
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
|
||||
public static function onPipeMessage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function onBeforeReload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function onAfterReload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
class ServerManager
|
||||
{
|
||||
|
||||
|
||||
public static function onManagerStart()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static function onManagerStop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
class Router
|
||||
{
|
||||
|
||||
private static array $_routers = [];
|
||||
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param Closure|array|string $callback
|
||||
*/
|
||||
public static function get(string $path, Closure|array|string $callback)
|
||||
{
|
||||
static::$_routers[$path] = $callback;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @return mixed
|
||||
*/
|
||||
public static function findPath($path): mixed
|
||||
{
|
||||
if (!isset(static::$_routers[$path])) {
|
||||
return null;
|
||||
}
|
||||
return static::$_routers[$path];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once 'ListenerHelper.php';
|
||||
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
* Class TCPServerListener
|
||||
* @package HttpServer\Service
|
||||
*/
|
||||
class TCPServerListener
|
||||
{
|
||||
|
||||
use ListenerHelper;
|
||||
|
||||
protected static mixed $_tcp;
|
||||
|
||||
|
||||
/**
|
||||
* UDPServerListener constructor.
|
||||
* @param Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
*/
|
||||
public static function instance(Server $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_TCP, SWOOLE_TCP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is tcp listener type.');
|
||||
}
|
||||
static::$_tcp = $server->addlistener($host, $port, $mode);
|
||||
static::$_tcp->set($settings['settings'] ?? []);
|
||||
static::$_tcp->on('receive', $settings['events'][BASEServerListener::SERVER_ON_RECEIVE] ?? [static::class, 'onReceive']);
|
||||
static::onConnectAndClose($server, static::$_tcp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public static function onConnect(Server $server, int $fd)
|
||||
{
|
||||
var_dump(__FILE__ . ':' . __LINE__);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
* @param int $reactor_id
|
||||
* @param string $data
|
||||
*/
|
||||
public static function onReceive(Server $server, int $fd, int $reactor_id, string $data)
|
||||
{
|
||||
var_dump($data);
|
||||
$server->send($fd, $data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public static function onClose(Server $server, int $fd)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace Task;
|
||||
|
||||
|
||||
use SInterface\TaskExecute;
|
||||
use Swoole\Server;
|
||||
|
||||
class ServerTask
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $task_id
|
||||
* @param int $src_worker_id
|
||||
* @param mixed $data
|
||||
*/
|
||||
public static function onTask(Server $server, int $task_id, int $src_worker_id, mixed $data)
|
||||
{
|
||||
try {
|
||||
$data = unserialize($data);
|
||||
if (!($data instanceof TaskExecute)) {
|
||||
return;
|
||||
}
|
||||
$data->execute();
|
||||
} catch (\Throwable $exception) {
|
||||
$data = [$exception->getMessage()];
|
||||
} finally {
|
||||
$server->finish($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param Server\Task $task
|
||||
*/
|
||||
public static function onCoroutineTask(Server $server, Server\Task $task)
|
||||
{
|
||||
try {
|
||||
$data = unserialize($task->data);
|
||||
if (!($data instanceof TaskExecute)) {
|
||||
return;
|
||||
}
|
||||
$data->execute();
|
||||
} catch (\Throwable $exception) {
|
||||
$data = [$exception->getMessage()];
|
||||
} finally {
|
||||
$server->finish($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $task_id
|
||||
* @param mixed $data
|
||||
*/
|
||||
public static function onFinish(Server $server, int $task_id, mixed $data)
|
||||
{
|
||||
if (!($data instanceof TaskExecute)) {
|
||||
return;
|
||||
}
|
||||
$data->finish($server, $task_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once 'ListenerHelper.php';
|
||||
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
* Class UDPServerListener
|
||||
* @package HttpServer\Service
|
||||
*/
|
||||
class UDPServerListener
|
||||
{
|
||||
|
||||
protected static mixed $_udp;
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
*/
|
||||
public static function instance(Server $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_UDP, SWOOLE_UDP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is udp listener type.');
|
||||
}
|
||||
static::$_udp = $server->addlistener($host, $port, $mode);
|
||||
static::$_udp->set($settings['settings'] ?? []);
|
||||
static::$_udp->on('packet', $settings['events'][BASEServerListener::SERVER_ON_PACKET] ?? [static::class, 'onPacket']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $data
|
||||
* @param array $clientInfo
|
||||
*/
|
||||
public static function onPacket(Server $server, string $data, array $clientInfo)
|
||||
{
|
||||
$server->sendto($clientInfo['address'], $clientInfo['port'], $data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Swoole\Http\Request;
|
||||
use Swoole\Http\Response;
|
||||
use Swoole\Server;
|
||||
use Swoole\WebSocket\Frame;
|
||||
|
||||
require_once 'ListenerHelper.php';
|
||||
|
||||
|
||||
/**
|
||||
* Class WebSocketServerListener
|
||||
* @package HttpServer\Service
|
||||
*/
|
||||
class WebSocketServerListener
|
||||
{
|
||||
|
||||
protected static Server\Port $_http;
|
||||
|
||||
|
||||
/**
|
||||
* UDPServerListener constructor.
|
||||
* @param Server|\Swoole\WebSocket\Server|\Swoole\Http\Server $server
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $mode
|
||||
* @param array|null $settings
|
||||
*/
|
||||
public static function instance(mixed $server, string $host, int $port, int $mode, ?array $settings = [])
|
||||
{
|
||||
if (!in_array($mode, [SWOOLE_TCP, SWOOLE_TCP6])) {
|
||||
trigger_error('Port mode ' . $host . '::' . $port . ' must is udp listener type.');
|
||||
}
|
||||
static::$_http = $server->addlistener($host, $port, $mode);
|
||||
static::$_http->set($settings['settings'] ?? []);
|
||||
static::$_http->on('handshake', $settings['events'][BASEServerListener::SERVER_ON_HANDSHAKE] ?? [static::class, 'onHandshake']);
|
||||
static::$_http->on('message', $settings['events'][BASEServerListener::SERVER_ON_MESSAGE] ?? [static::class, 'onMessage']);
|
||||
static::$_http->on('close', $settings['events'][BASEServerListener::SERVER_ON_CLOSE] ?? [static::class, 'onClose']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Response $response
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function onHandshake(Request $request, Response $response)
|
||||
{
|
||||
/** @var \Swoole\WebSocket\Server $server */
|
||||
$secWebSocketKey = $request->header['sec-websocket-key'];
|
||||
$patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
|
||||
if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
|
||||
throw new Exception('protocol error.', 500);
|
||||
}
|
||||
$key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
|
||||
$headers = [
|
||||
'Upgrade' => 'websocket',
|
||||
'Connection' => 'Upgrade',
|
||||
'Sec-websocket-Accept' => $key,
|
||||
'Sec-websocket-Version' => '13',
|
||||
];
|
||||
if (isset($request->header['sec-websocket-protocol'])) {
|
||||
$headers['Sec-websocket-Protocol'] = $request->header['sec-websocket-protocol'];
|
||||
}
|
||||
foreach ($headers as $key => $val) {
|
||||
$response->setHeader($key, $val);
|
||||
}
|
||||
|
||||
$response->setStatusCode(101);
|
||||
$response->end();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// public static function decode($received): ?string
|
||||
// {
|
||||
// $decoded = null;
|
||||
// $buffer = $received;
|
||||
// $len = ord($buffer[1]) & 127;
|
||||
// if ($len === 126) {
|
||||
// $masks = substr($buffer, 4, 4);
|
||||
// $data = substr($buffer, 8);
|
||||
// } else {
|
||||
// if ($len === 127) {
|
||||
// $masks = substr($buffer, 10, 4);
|
||||
// $data = substr($buffer, 14);
|
||||
// } else {
|
||||
// $masks = substr($buffer, 2, 4);
|
||||
// $data = substr($buffer, 6);
|
||||
// }
|
||||
// }
|
||||
// for ($index = 0; $index < strlen($data); $index++) {
|
||||
// $decoded .= $data[$index] ^ $masks[$index % 4];
|
||||
// }
|
||||
//
|
||||
// return $decoded;
|
||||
// }
|
||||
//
|
||||
// const BINARY_TYPE_BLOB = "\x81";
|
||||
//
|
||||
//
|
||||
// public static function encode($buffer): string
|
||||
// {
|
||||
// $len = strlen($buffer);
|
||||
//
|
||||
// $first_byte = self::BINARY_TYPE_BLOB;
|
||||
//
|
||||
// if ($len <= 125) {
|
||||
// $encode_buffer = $first_byte . chr($len) . $buffer;
|
||||
// } else {
|
||||
// if ($len <= 65535) {
|
||||
// $encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer;
|
||||
// } else {
|
||||
// //pack("xxxN", $len)pack函数只处理2的32次方大小的文件,实际上2的32次方已经4G了。
|
||||
// $encode_buffer = $first_byte . chr(127) . pack("xxxxN", $len) . $buffer;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return $encode_buffer;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private static function socketConnection($server, $fd, $data)
|
||||
// {
|
||||
// $http_protocol = [];
|
||||
// foreach ($data as $key => $datum) {
|
||||
// if (empty($datum) || $key == 0) {
|
||||
// continue;
|
||||
// }
|
||||
// [$key, $value] = explode(': ', $datum);
|
||||
//
|
||||
// $http_protocol[trim($key)] = trim($value);
|
||||
// }
|
||||
//
|
||||
// $key = base64_encode(sha1($http_protocol['Sec-WebSocket-Key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
|
||||
// $headers = [
|
||||
// 'HTTP/1.1 101 Switching Protocols',
|
||||
// 'Upgrade: websocket',
|
||||
// 'Connection: Upgrade',
|
||||
// 'Sec-WebSocket-Accept: ' . $key,
|
||||
// 'Sec-WebSocket-Version: 13',
|
||||
// ];
|
||||
// if (isset($http_protocol['Sec-WebSocket-Protocol'])) {
|
||||
// $headers[] = 'Sec-WebSocket-Protocol: ' . $http_protocol['Sec-WebSocket-Protocol'];
|
||||
// }
|
||||
// $server->send($fd, implode("\r\n", $headers) . "\r\n\r\n");
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public static function onConnect(Server $server, int $fd)
|
||||
{
|
||||
var_dump(__FILE__ . ':' . __LINE__);
|
||||
$server->confirm($fd);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param \Swoole\WebSocket\Server|Server $server
|
||||
* @param Frame $frame
|
||||
*/
|
||||
public static function onMessage(\Swoole\WebSocket\Server|Server $server, Frame $frame)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $fd
|
||||
*/
|
||||
public static function onClose(Server $server, int $fd)
|
||||
{
|
||||
var_dump($server->getClientInfo($fd));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
<?php
|
||||
|
||||
|
||||
return [
|
||||
'server' => [
|
||||
'settings' => [
|
||||
'worker_num' => swoole_cpu_num(),
|
||||
'reactor_num' => swoole_cpu_num(),
|
||||
'dispatch_mode' => 3,
|
||||
'task_worker_num' => 1,
|
||||
'enable_coroutine' => true,
|
||||
'task_enable_coroutine' => true,
|
||||
'daemonize' => 0,
|
||||
'open_tcp_keepalive' => 1,
|
||||
'heartbeat_check_interval' => 60,
|
||||
'heartbeat_idle_time' => 600,
|
||||
'tcp_keepidle' => 3,
|
||||
'tcp_keepinterval' => 1,
|
||||
'tcp_keepcount' => 2,
|
||||
'max_wait_time' => 60,
|
||||
'reload_async' => true,
|
||||
'enable_delay_receive' => true,
|
||||
'tcp_fastopen' => 1,
|
||||
'tcp_defer_accept' => 1
|
||||
],
|
||||
'events' => [
|
||||
BASEServerListener::SERVER_ON_PIPE_MESSAGE => [ServerBase::class, 'onPipeMessage'],
|
||||
BASEServerListener::SERVER_ON_SHUTDOWN => [ServerBase::class, 'onShutdown'],
|
||||
BASEServerListener::SERVER_ON_WORKER_START => [ServerWorker::class, 'onWorkerStart'],
|
||||
BASEServerListener::SERVER_ON_WORKER_ERROR => [ServerWorker::class, 'onWorkerError'],
|
||||
BASEServerListener::SERVER_ON_WORKER_EXIT => [ServerWorker::class, 'onWorkerExit'],
|
||||
BASEServerListener::SERVER_ON_WORKER_STOP => [ServerWorker::class, 'onWorkerStop'],
|
||||
BASEServerListener::SERVER_ON_MANAGER_START => [ServerManager::class, 'onManagerStart'],
|
||||
BASEServerListener::SERVER_ON_MANAGER_STOP => [ServerManager::class, 'onManagerStop'],
|
||||
BASEServerListener::SERVER_ON_BEFORE_RELOAD => [ServerBase::class, 'onBeforeReload'],
|
||||
BASEServerListener::SERVER_ON_AFTER_RELOAD => [ServerBase::class, 'onAfterReload'],
|
||||
BASEServerListener::SERVER_ON_START => [ServerBase::class, 'onStart'],
|
||||
],
|
||||
'ports' => [
|
||||
[
|
||||
'type' => BASEServerListener::SERVER_TYPE_HTTP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9002,
|
||||
'mode' => SWOOLE_SOCK_TCP,
|
||||
'events' => [
|
||||
BASEServerListener::SERVER_ON_REQUEST => [HTTPServerListener::class, 'onRequest'],
|
||||
],
|
||||
'settings' => [
|
||||
'open_http_protocol' => true,
|
||||
'open_http2_protocol' => false,
|
||||
'http_parse_cookie' => true,
|
||||
'http_compression' => true,
|
||||
'http_compression_level' => 5,
|
||||
'enable_unsafe_event' => false,
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => BASEServerListener::SERVER_TYPE_WEBSOCKET,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9001,
|
||||
'mode' => SWOOLE_SOCK_TCP,
|
||||
'settings' => [
|
||||
'open_http_protocol' => false,
|
||||
'open_http2_protocol' => false
|
||||
],
|
||||
'events' => [
|
||||
BASEServerListener::SERVER_ON_CONNECT => [WebSocketServerListener::class, 'onConnect'],
|
||||
BASEServerListener::SERVER_ON_HANDSHAKE => [WebSocketServerListener::class, 'onHandshake'],
|
||||
BASEServerListener::SERVER_ON_MESSAGE => [WebSocketServerListener::class, 'onMessage'],
|
||||
BASEServerListener::SERVER_ON_CLOSE => [WebSocketServerListener::class, 'onClose'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => BASEServerListener::SERVER_TYPE_TCP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9003,
|
||||
'mode' => SWOOLE_SOCK_TCP,
|
||||
'events' => [
|
||||
BASEServerListener::SERVER_ON_CONNECT => [TCPServerListener::class, 'onConnect'],
|
||||
BASEServerListener::SERVER_ON_RECEIVE => [TCPServerListener::class, 'onReceive'],
|
||||
BASEServerListener::SERVER_ON_CLOSE => [TCPServerListener::class, 'onClose'],
|
||||
]
|
||||
],
|
||||
[
|
||||
'type' => BASEServerListener::SERVER_TYPE_UDP,
|
||||
'host' => '0.0.0.0',
|
||||
'port' => 9004,
|
||||
'mode' => SWOOLE_SOCK_UDP,
|
||||
'events' => [
|
||||
BASEServerListener::SERVER_ON_PACKET => [UDPServerListener::class, 'onPacket'],
|
||||
]
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SInterface\TaskExecute;
|
||||
use Swoole\Server;
|
||||
|
||||
|
||||
/**
|
||||
* Class RegisterTask
|
||||
*/
|
||||
class RegisterTask implements TaskExecute
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* RegisterTask constructor.
|
||||
* @param mixed $data
|
||||
*/
|
||||
public function __construct(public mixed $data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
// TODO: Implement execute() method.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param int $task_id
|
||||
*/
|
||||
public function finish(Server $server, int $task_id)
|
||||
{
|
||||
// TODO: Implement finish() method.
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
use SInterface\CustomProcess;
|
||||
use Swoole\Process;
|
||||
|
||||
|
||||
/**
|
||||
* Class RelationshipSystemProcess
|
||||
*/
|
||||
class RelationshipSystemProcess implements CustomProcess
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* RelationshipSystemProcess constructor.
|
||||
* @param mixed $params
|
||||
*/
|
||||
public function __construct(public mixed $params)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Process $process
|
||||
* @return string
|
||||
*/
|
||||
public function getProcessName(Process $process): string
|
||||
{
|
||||
return 'system-service: ' . get_called_class() . '[' . $process->pid . ']';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function onHandler(Process $process): void
|
||||
{
|
||||
// TODO: Implement onHandler() method.
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user