feat: 实现TCP Server
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
namespace app\flow;
|
||||
|
||||
use app\config\Config;
|
||||
use app\utils\Logger;
|
||||
|
||||
/**
|
||||
* 操作员会话管理器(进程内单例)
|
||||
*
|
||||
* 职责:记录每个读卡器上最近一次刷过的人员卡信息。
|
||||
* 流程规则:
|
||||
* 1. 先刷人员卡 → 记录到本管理器(以 readerId 为 key)
|
||||
* 2. 再刷内镜卡 → 从本管理器取出操作员信息,写入 ProcessContext,随即清除会话
|
||||
* 3. 无论内镜卡刷卡结果正确还是错误,会话均立即清除,下次需重新刷人员卡
|
||||
*/
|
||||
class OperatorSessionManager
|
||||
{
|
||||
/**
|
||||
* 单例实例
|
||||
*/
|
||||
private static ?self $instance = null;
|
||||
|
||||
/**
|
||||
* 会话存储:[readerId => ['id'=>..., 'name'=>..., 'rfid'=>...]]
|
||||
*/
|
||||
private array $sessions = [];
|
||||
|
||||
/**
|
||||
* 人员刷卡记录缓存记录多久
|
||||
*/
|
||||
public int $expire = 0;
|
||||
|
||||
/**
|
||||
* 人员刷卡记录记录哪些读卡器的
|
||||
* 设置为空则表示所有读卡器
|
||||
*/
|
||||
public array $recordReaders = [];
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$this->expire = Config::getInstance()->openCardRecordCacheTime;
|
||||
$this->recordReaders = Config::getInstance()->openCardRecordReaders;
|
||||
}
|
||||
|
||||
public static function getInstance(): self
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置单例(测试用)
|
||||
*/
|
||||
public static function resetInstance(): void
|
||||
{
|
||||
self::$instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录某读卡器上的操作员信息
|
||||
*
|
||||
* @param string $readerId 读卡器ID
|
||||
* @param string $userId 操作员ID
|
||||
* @param string $userName 操作员姓名
|
||||
* @param string $userRfid 操作员RFID
|
||||
*/
|
||||
public function setOperator(string $readerId, string $userId, string $userName, string $userRfid): void
|
||||
{
|
||||
$this->sessions[$readerId] = [
|
||||
'id' => $userId,
|
||||
'name' => $userName,
|
||||
'rfid' => $userRfid,
|
||||
'time' => time(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取某读卡器上记录的操作员信息
|
||||
*
|
||||
* @param string $readerId 读卡器ID
|
||||
* @return array|null ['id'=>..., 'name'=>..., 'rfid'=>...] 或 null(未登记)
|
||||
*/
|
||||
public function getOperator(string $readerId, string $readerType): ?array
|
||||
{
|
||||
$cache = $this->sessions[$readerId] ?? null;
|
||||
$time = $cache['time'];
|
||||
Logger::debug("OperatorSessionManager::getOperator($readerId, $readerType)");
|
||||
|
||||
if (empty($cache)) return null;
|
||||
if ($this->expire > 0 && isset($time) && (time() - $time) <= $this->expire) {
|
||||
if (in_array($readerType, $this->recordReaders) && empty($this->recordReaders)) {
|
||||
return $cache;
|
||||
}
|
||||
}
|
||||
return $this->pop($readerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断某读卡器是否已有操作员登记
|
||||
*/
|
||||
public function hasOperator(string $readerId): bool
|
||||
{
|
||||
return isset($this->sessions[$readerId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除某读卡器的操作员会话(内镜卡刷卡后立即调用)
|
||||
*/
|
||||
public function clearOperator(string $readerId): void
|
||||
{
|
||||
unset($this->sessions[$readerId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有会话(测试用)
|
||||
*/
|
||||
public function clearAll(): void
|
||||
{
|
||||
$this->sessions = [];
|
||||
}
|
||||
|
||||
public function pop(string $readerId): ?array
|
||||
{
|
||||
$op = $this->getOperator($readerId);
|
||||
$this->clearOperator($readerId);
|
||||
return $op;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user