Files
2026-01-28 23:48:20 +08:00

342 lines
12 KiB
PHP

<?php
namespace freedom\utils;
use app\models\table\Table;
/**
* TODO swooleSession工具类
* Class SocketSession
* @package freedom\utils
*/
class SocketSession
{
/**
* 大房名称,所有有效连接都会加入
* @var string
*/
const HOUSE_NAME = 'house';
/**
* 控制台房间
* @var string
*/
const SPACE_ROOM_NAME = 'space';
/**
* 会员房间
* @var string
*/
const USER_ROOM_NAME = 'user';
/**
* 扫描房间
* @var string
*/
const SCAN_ROOM_NAME = 'scan';
/**
* 接口房间
* @var string
*/
const API_ROOM_NAME = 'api';
/**
* 经理房间
* @var string
*/
const MANAGER_ROOM_NAME = 'manager';
/**
* TODO 连接socket成功后保存session的工具方法,所有连接将加入house,不同连接模式加入不同的房间
* @param array $event
* @param string $mode
* @return void;
*/
public static function saveSocketSession(array $event, string $mode){
$ws = app('\think\swoole\WebSocket');
$fd = $ws->getSender();
//保存信息到table
$tableFd = app('swoole.table.fd');
if($mode == 'space'){
$tableSpace = app('swoole.table.space');
$tableId = $event['table_id'];
$tableName = $event['table_name'];
//查找原本是否有登录
$spaceInfo = $tableSpace->get((string) $tableId);
if(!empty($spaceInfo)){
$tableSpace->del((string) $tableId);
$tableFd->del((string) $spaceInfo['fd']);
$ws->setSender(0)->to($spaceInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
}
$tableFd->set((string) $fd,[
'mode' => 'space',
'table_id' => $tableId,
'table_name' => $tableName,
]);
$tableSpace->set((string) $tableId,[
'fd' => $fd,
'mode' => 'space',
'table_name' => $tableName,
]);
$ws->join(self::SPACE_ROOM_NAME);
}elseif($mode == 'scan'){
$tableScan = app('swoole.table.scan');
$appid = $event['appid'];
//查找原本是否有登录
$scanInfo = $tableScan->get((string) $appid);
if(!empty($scanInfo)){
$tableScan->del((string) $appid);
$tableFd->del((string) $scanInfo['fd']);
$ws->setSender(0)->to($scanInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
}
$tableFd->set((string) $fd,[
'mode' => 'scan',
'scan_appid' => $appid,
]);
$tableScan->set((string) $appid,[
'fd' => $fd,
'mode' => 'scan',
'appid' => $appid,
]);
$ws->join(self::SCAN_ROOM_NAME);
}elseif($mode == 'user'){
$tableUser = app('swoole.table.user');
$user_id = $event['user_id'];
$username = $event['username'];
//查找原本是否有登录
$userInfo = $tableUser->get((string) $user_id);
if(!empty($userInfo)){
$tableUser->del((string) $user_id);
$tableFd->del((string) $userInfo['fd']);
$ws->setSender(0)->to($userInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
}
$tableFd->set((string) $fd,[
'mode' => 'user',
'user_id' => $user_id,
'username' => $username,
]);
$tableUser->set((string) $user_id,[
'fd' => $fd,
'mode' => 'user',
'username' => $username,
'isToBet' => 1,
'toBetTime' => time(),
'isToRob' => 1,
'toRobTime' => time(),
'isToCancelBet' => 1,
'toCancelBetTime' => time(),
'isToSeat' => 1,
'toSeatTime' => time(),
'isToLeaveSeat' => 1,
'toLeaveSeatTime' => time(),
]);
$ws->join(self::USER_ROOM_NAME);
} elseif ($mode == 'api'){
$tableApi = app('swoole.table.api');
$appid = $event['appid'];
//查找原本是否有登录
$apiInfo = $tableApi->get((string) $appid);
if(empty($scanInfo)){
$tableApi->del((string) $appid);
$tableFd->del((string) $apiInfo['fd']);
}
$tableFd->set((string) $fd,[
'mode' => 'scan',
'api_appid' => $appid,
]);
$tableApi->set((string) $appid,[
'fd' => $fd,
'mode' => 'api',
'appid' => $appid,
]);
$ws->join(self::API_ROOM_NAME);
} elseif ($mode == 'manager'){
$tableManager = app('swoole.table.manager');
$user_id = $event['user_id'];
$username = $event['username'];
//查找原本是否有登录
$userInfo = $tableManager->get((string) $user_id);
if(!empty($userInfo)){
$tableManager->del((string) $user_id);
$tableFd->del((string) $userInfo['fd']);
$ws->setSender(0)->to($userInfo['fd'])->emit('RepeatedEntry',['status' => true, 'msg' => 'repeated_entry']);
}
$tableFd->set((string) $fd,[
'mode' => 'manager',
'user_id' => $user_id,
'username' => $username,
]);
$tableManager->set((string) $user_id,[
'fd' => $fd,
'mode' => 'manager',
'username' => $username,
]);
//电投用
$ws->join(self::MANAGER_ROOM_NAME);
}
//加入房子
$ws->join(self::HOUSE_NAME);
}
/**
* TODO 检查房间是否存在有效连接
* @param int $fd
* @param string $mode
* @return bool;
*/
public static function checkSocketSession(int $fd, string $mode): bool
{
$tableFd = app('swoole.table.fd');
$fdInfo = $tableFd->get((string) $fd);
if(!empty($fdInfo)){
if($mode == 'space' || $mode == 'sb'){
$tableSpace = app('swoole.table.space');
$spaceInfo = $tableSpace->get((string) $fdInfo['table_id']);
if(!empty($spaceInfo)){
return true;
}else{
return false;
}
}elseif($mode == 'scan'){
$tableScan = app('swoole.table.scan');
$scanInfo = $tableScan->get((string) $fdInfo['scan_appid']);
if(!empty($scanInfo)){
return true;
}else{
return false;
}
}elseif($mode == 'user'){
$tableUser = app('swoole.table.user');
$userInfo = $tableUser->get((string) $fdInfo['user_id']);
if(!empty($userInfo)){
return true;
}else{
return false;
}
}else{
return false;
}
}else{
return false;
}
}
/**
* TODO 事件执行的权限检查
* @param array $event
* @param string $mode
* @return array;
*/
public static function preliminaryCheck(array $event, string $mode): array
{
$ws = app('\think\swoole\WebSocket');
$tableId = intval($event['table_id']);
$tableInfo = Table::get($tableId);
if ($mode == 'scan' && $tableInfo['scanner_type'] == 2) {
$mode = 'sb';
}
if(SocketSession::checkSocketSession(intval($ws->getSender()),$mode) == false) {
return ['status' => false, 'msg' => 'no_right'];
}
if(!$tableInfo) {
return ['status' => false, 'msg' => 'not_table_data'];
}
return ['status' => true, 'data' => $tableInfo];
}
/**
* TODO 检查是否重复提交
* @param int $fd
* @param string $mode
* @param string $e
* @return bool;
*/
public static function checkRepeat(int $fd, string $mode, string $e): bool
{
$tableFd = app('swoole.table.fd');
$fdInfo = $tableFd->get((string) $fd);
if($mode == 'user'){
$user_id = $fdInfo['user_id'];
$tableUser = app('swoole.table.user');
$userInfo = $tableUser->get((string) $user_id);
if(!empty($userInfo)){
if($e == 'isToBet'){
if($userInfo['isToBet'] == 1 || $userInfo['toBetTime'] <= (time() - 10)){
$userInfo['isToBet'] = 0;
$userInfo['toBetTime'] = time();
$tableUser->set((string) $user_id, $userInfo);
return true;
}else{
return false;
}
}elseif($e == 'isToRob'){
if($userInfo['isToRob'] == 1 || $userInfo['toRobTime'] <= (time() - 10)){
$userInfo['isToRob'] = 0;
$userInfo['toRobTime'] = time();
$tableUser->set((string) $user_id, $userInfo);
return true;
}else{
return false;
}
}elseif($e == 'isToCancelBet'){
if($userInfo['isToCancelBet'] == 1 || $userInfo['toCancelBetTime'] <= (time() - 10)){
$userInfo['isToCancelBet'] = 0;
$userInfo['toCancelBetTime'] = time();
$tableUser->set((string) $user_id, $userInfo);
return true;
}else{
return false;
}
}elseif($e == 'isToSeat'){
if($userInfo['isToSeat'] == 1 || $userInfo['toSeatTime'] <= (time() - 10)){
$userInfo['isToSeat'] = 0;
$userInfo['toSeatTime'] = time();
$tableUser->set((string) $user_id, $userInfo);
return true;
}else{
return false;
}
}elseif($e == 'isToLeaveSeat'){
if($userInfo['isToLeaveSeat'] == 1 || $userInfo['toLeaveSeatTime'] <= (time() - 10)){
$userInfo['isToLeaveSeat'] = 0;
$userInfo['toLeaveSeatTime'] = time();
$tableUser->set((string) $user_id, $userInfo);
return true;
}else{
return false;
}
}else{
return false;
}
}else{
return false;
}
}elseif($mode == 'space'){
return false;
}else{
return false;
}
}
/**
* TODO 重置重复值
* @param int $fd
* @param string $mode
* @param string $e
* @return void;
*/
public static function resetRepeat(int $fd, string $mode, string $e)
{
$tableFd = app('swoole.table.fd');
$fdInfo = $tableFd->get((string) $fd);
if($mode == 'user'){
$user_id = $fdInfo['user_id'];
$tableUser = app('swoole.table.user');
$userInfo = $tableUser->get((string) $user_id);
$userInfo[$e] = 1;
$tableUser->set((string) $user_id, $userInfo);
}
}
}