<?php use tourze\Base\Config; use tourze\Route\Route; use tourze\StatServer\Cache; use tourze\View\View; if (is_file(__DIR__ . '/vendor/autoload.php')) { require_once __DIR__ . '/vendor/autoload.php'; } ini_set('display_errors', 'on'); if (!defined('ROOT_PATH')) { define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR); } if (!defined('WEB_PATH')) { define('WEB_PATH', ROOT_PATH . 'web' . DIRECTORY_SEPARATOR); } Config::addPath(ROOT_PATH . 'config' . DIRECTORY_SEPARATOR); View::addPath(ROOT_PATH . 'view' . DIRECTORY_SEPARATOR); Cache::$serverIpList = Config::load('statServer')->get('serverIpList'); // 指定控制器命名空间 Route::$defaultNamespace = '\\tourze\\StatServer\\Controller\\'; Route::set('stat-web', '(<controller>(/<action>(/<id>)))')->defaults(['controller' => 'Main', 'action' => 'index']); // 创建类别名 @class_alias('\\tourze\\StatServer\\Protocol\\Statistic', '\\Workerman\\Protocols\\Statistic');
public function actionIndex() { $act = isset($_GET['act']) ? $_GET['act'] : 'home'; $errorMsg = $noticeMsg = $successMsg = $ipListStr = ''; $action = 'save-server-list'; switch ($act) { case 'detect-server': // 创建udp socket $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1); $buffer = json_encode(['cmd' => 'REPORT_IP']) . "\n"; // 广播 socket_sendto($socket, $buffer, strlen($buffer), 0, '255.255.255.255', Config::load('statServer')->get('providerPort')); // 超时相关 $time_start = microtime(true); $global_timeout = 1; $ipList = []; $recv_timeout = ['sec' => 0, 'usec' => 8000]; socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $recv_timeout); // 循环读数据 while (microtime(true) - $time_start < $global_timeout) { $buf = $host = $port = ''; if (@socket_recvfrom($socket, $buf, 65535, 0, $host, $port)) { $ipList[$host] = $host; } } // 过滤掉已经保存的ip $count = 0; foreach ($ipList as $ip) { if (!isset(Cache::$serverIpList[$ip])) { $ipListStr .= $ip . "\r\n"; $count++; } } $action = 'add-to-server-list'; $noticeMsg = "探测到{$count}个新数据源"; break; case 'add-to-server-list': if (empty($_POST['ip_list'])) { $errorMsg = "保存的ip列表为空"; break; } $ipList = explode("\n", $_POST['ip_list']); if ($ipList) { foreach ($ipList as $ip) { $ip = trim($ip); if (false !== ip2long($ip)) { Cache::$serverIpList[$ip] = $ip; } } } $successMsg = "添加成功"; foreach (Cache::$serverIpList as $ip) { $ipListStr .= $ip . "\r\n"; } break; case 'save-server-list': if (empty($_POST['ip_list'])) { $errorMsg = "保存的ip列表为空"; break; } Cache::$serverIpList = []; $ipList = explode("\n", $_POST['ip_list']); if ($ipList) { foreach ($ipList as $ip) { $ip = trim($ip); if (false !== ip2long($ip)) { Cache::$serverIpList[$ip] = $ip; } } } $successMsg = "保存成功"; foreach (Cache::$serverIpList as $ip) { $ipListStr .= $ip . "\r\n"; } break; default: foreach (Cache::$serverIpList as $ip) { $ipListStr .= $ip . "\r\n"; } } $this->template->set('admin/index', ['act' => $act, 'action' => $action, 'successMsg' => $successMsg, 'noticeMsg' => $noticeMsg, 'errorMsg' => $errorMsg, 'ipListStr' => $ipListStr]); }
/** * 批量请求 * * @param array $requestBufferArray ['ip:port'=>req_buf, 'ip:port'=>req_buf, ...] * @return mixed multitype:unknown string */ public static function multiRequest($requestBufferArray) { Base::getLog()->info(__METHOD__ . ' call multiRequest - start', ['arg' => $requestBufferArray]); Cache::$lastSuccessIpArray = []; $clientArray = $sockToIP = $ipList = $sockToAddress = []; foreach ($requestBufferArray as $address => $buffer) { $temp = explode(':', $address); $ip = array_shift($temp); Base::getLog()->info(__METHOD__ . ' loop to get remote buffer', ['ip' => $ip, 'address' => $address, 'buffer' => $buffer]); $ipList[$ip] = $ip; $client = stream_socket_client("tcp://{$address}", $errNumber, $errorMsg, 1); if (!$client) { Base::getLog()->error(__METHOD__ . ' create socket failed', ['address' => $address, 'errNumber' => $errNumber, 'errMsg' => $errorMsg]); continue; } $clientArray[$address] = $client; stream_set_timeout($clientArray[$address], 0, 100000); fwrite($clientArray[$address], $buffer); stream_set_blocking($clientArray[$address], 0); $sockToAddress[(int) $client] = $address; } $read = $clientArray; $write = $except = $readBuffer = []; $timeStart = microtime(true); $timeout = 0.99; // 轮询处理数据 while (count($read) > 0) { if (@stream_select($read, $write, $except, 0, 200000)) { foreach ($read as $socket) { $address = $sockToAddress[(int) $socket]; $buf = fread($socket, 8192); if (!$buf) { if (feof($socket)) { unset($clientArray[$address]); } continue; } if (!isset($readBuffer[$address])) { $readBuffer[$address] = $buf; } else { $readBuffer[$address] .= $buf; } // 数据接收完毕 if (($len = strlen($readBuffer[$address])) && $readBuffer[$address][$len - 1] === "\n") { unset($clientArray[$address]); } } } // 超时了 if (microtime(true) - $timeStart > $timeout) { break; } $read = $clientArray; } foreach ($readBuffer as $address => $buf) { $temp = explode(':', $address); $ip = array_shift($temp); Cache::$lastSuccessIpArray[$ip] = $ip; } Base::getLog()->info(__METHOD__ . ' Cache::$lastFailedIpArray', Cache::$lastFailedIpArray); Base::getLog()->info(__METHOD__ . ' $ipList', $ipList); Cache::$lastFailedIpArray = array_diff($ipList, Cache::$lastSuccessIpArray); ksort($readBuffer); return $readBuffer; }