134 lines
3.7 KiB
PHP
134 lines
3.7 KiB
PHP
<?php
|
||
|
||
namespace app\process;
|
||
|
||
use app\flow\FlowMain;
|
||
use app\net\PacketContext;
|
||
use app\net\parsers\PacketParserFactory;
|
||
use app\utils\Logger;
|
||
use support\Db;
|
||
use support\Log;
|
||
use Workerman\Connection\TcpConnection;
|
||
|
||
class TcpServer
|
||
{
|
||
/**
|
||
* @var array 连接池 map<ip, connection> 连接池,key为客户端IP,value为连接对象
|
||
*/
|
||
private static array $connections = [];
|
||
|
||
public function __construct()
|
||
{
|
||
// 初始化 FlowMain
|
||
FlowMain::getInstance();
|
||
}
|
||
|
||
/**
|
||
* 获取连接池
|
||
*/
|
||
public static function getConnections(): array
|
||
{
|
||
return self::$connections;
|
||
}
|
||
|
||
/**
|
||
* 获取链接
|
||
*/
|
||
public static function getConnection(string $ip): ?TcpConnection
|
||
{
|
||
return self::$connections[$ip] ?? null;
|
||
}
|
||
|
||
/**
|
||
* 获取所有IP
|
||
*/
|
||
public static function getAllIp(): array
|
||
{
|
||
return array_keys(self::$connections);
|
||
}
|
||
|
||
/**
|
||
* 获取所有连接
|
||
*/
|
||
public static function getAllConnections(): array
|
||
{
|
||
return self::$connections;
|
||
}
|
||
|
||
/**
|
||
* Worker启动时触发
|
||
*/
|
||
public function onWorkerStart($worker): void
|
||
{
|
||
Logger::info("TcpServer started");
|
||
}
|
||
|
||
|
||
/**
|
||
* 连接时触发
|
||
*/
|
||
public function onConnect(TcpConnection $connection): void
|
||
{
|
||
self::$connections[$connection->getRemoteIp()] = $connection;
|
||
Log::info("客户端链接到主机: {$connection->getRemoteIp()}");
|
||
}
|
||
|
||
/**
|
||
* 接收数据时触发
|
||
*/
|
||
public function onMessage(TcpConnection $connection, $data): void
|
||
{
|
||
$ip = $connection->getRemoteIp();
|
||
self::$connections[$ip] = $connection;
|
||
$packet = PacketParserFactory::new($data);
|
||
$context = new PacketContext(self::getConnections(), $connection, $packet);
|
||
$this->logMessage($packet, $ip);
|
||
if ($packet->isMatched) {
|
||
$result = FlowMain::getInstance()->main($context);
|
||
$connection->send($result->getFullVoice());
|
||
} else {
|
||
$connection->send("Packet is not matched");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 连接关闭时触发
|
||
*/
|
||
public function onClose(TcpConnection $connection): void
|
||
{
|
||
unset(self::$connections[$connection->getRemoteIp()]);
|
||
Logger::info("客户端已断开连接:{$connection->getRemoteIp()}");
|
||
}
|
||
|
||
/**
|
||
* @param \app\net\Packet $packet
|
||
* @param string $ip
|
||
* @return void
|
||
*/
|
||
public function logMessage(\app\net\Packet $packet, string $ip): void
|
||
{
|
||
if ($packet->isMatched) {
|
||
Logger::debug(Logger::generateTextBox([
|
||
"---------------------------- PACKET --------------------------------",
|
||
"IP Address : {$ip}",
|
||
"Packet Length: {$packet->length}",
|
||
"Hex Packet : {$packet->hexString}",
|
||
"Packet Type : {$packet->hexType->name}",
|
||
"---------------------------- DATA --------------------------------",
|
||
"Reader Info : {$packet->reader}",
|
||
"Card Info : {$packet->card}",
|
||
"Gateway Info : {$packet->gateway}",
|
||
]));
|
||
} else {
|
||
Logger::debug("Packet is not matched");
|
||
Logger::debug(Logger::generateTextBox([
|
||
"---------------------------- PACKET --------------------------------",
|
||
"IP Address : {$ip}",
|
||
"Packet Length: {$packet->length}",
|
||
"Packet Type : {$packet->hexType->name}",
|
||
"---------------------------- DATA --------------------------------",
|
||
"Hex Packet : {$packet->hexString}"
|
||
]));
|
||
}
|
||
}
|
||
} |