PHP页面中建立的远程WMI连接为何会自动断开?如何维持连接至页面存续期或设置会话时长
如何保持PHP中远程WMI连接的会话时长?
我通过PHP使用WMI读取远程PC的操作系统版本、CPU负载、内存大小等数据,代码逻辑是先建立WMI连接再执行查询,但遇到了连接时效问题:
- 首次打开页面时,建立初始WMI连接耗时15-20秒,之后可正常获取数据
- 若在3-5秒内刷新页面,数据会立即更新(仅需1-2秒)
- 但页面打开后间隔1分钟再刷新,连接就会丢失,必须重新建立连接,又要花费20秒才能拿到更新后的数据
看起来WMI连接会在一段时间后自动断开,请问有没有办法让连接保持至页面打开状态存续期间,或者能否设置比如5分钟的会话时长?
相关PHP代码如下:
<?php // Connection to WMI **************** $strComputer = "10.92.114.85"; $objSWbemLocator = new COM ("WbemScripting.SWbemLocator"); $objSWbemServices = $objSWbemLocator->ConnectServer($strComputer, "root\cimv2", "user", "password"); $objSWbemServices->Security_->ImpersonationLevel = 3; $obj = $objSWbemServices; $Processor = $obj->ExecQuery("Select * from Win32_Processor"); $PhysicalMemory = $obj->ExecQuery("Select * from Win32_PhysicalMemory"); // WMI Processor Informations foreach ( $Processor as $wmi_Processor ) { $CPUName = $wmi_Processor->Name; $CPU3264bit = $wmi_Processor->AddressWidth; $CPUSpeed = $wmi_Processor->MaxClockSpeed; $CPUCores = $wmi_Processor->NumberOfCores; } // showing values on screen ?>
可行的解决方案
1. 缓存查询结果,避免重复建立连接
PHP是无状态的脚本语言,每个请求结束后进程会销毁,无法直接在不同请求间保持COM类型的WMI连接。最实际的优化方式是缓存查询结果,设置合理的有效期,避免每次请求都重新建立连接:
修改后的示例代码(使用Session缓存,有效期5分钟):
<?php session_start(); // 缓存配置:键名+有效期(5分钟=300秒) $cacheKey = 'remote_wmi_system_data'; $cacheExpire = 300; // 优先使用缓存数据 if (isset($_SESSION[$cacheKey]) && time() - $_SESSION[$cacheKey]['timestamp'] < $cacheExpire) { $cachedData = $_SESSION[$cacheKey]['data']; extract($cachedData); // 直接提取缓存中的CPU相关变量 } else { // 重新建立WMI连接并查询 $strComputer = "10.92.114.85"; $objSWbemLocator = new COM("WbemScripting.SWbemLocator"); $objSWbemServices = $objSWbemLocator->ConnectServer($strComputer, "root\cimv2", "user", "password"); $objSWbemServices->Security_->ImpersonationLevel = 3; $obj = $objSWbemServices; $Processor = $obj->ExecQuery("Select * from Win32_Processor"); foreach ($Processor as $wmi_Processor) { $CPUName = $wmi_Processor->Name; $CPU3264bit = $wmi_Processor->AddressWidth; $CPUSpeed = $wmi_Processor->MaxClockSpeed; $CPUCores = $wmi_Processor->NumberOfCores; } // 将查询结果存入Session缓存 $_SESSION[$cacheKey] = [ 'timestamp' => time(), 'data' => [ 'CPUName' => $CPUName, 'CPU3264bit' => $CPU3264bit, 'CPUSpeed' => $CPUSpeed, 'CPUCores' => $CPUCores ] ]; } // 页面输出示例 echo "<h3>远程PC硬件信息</h3>"; echo "<ul>"; echo "<li>CPU名称:{$CPUName}</li>"; echo "<li>架构:{$CPU3264bit}位</li>"; echo "<li>最高主频:{$CPUSpeed}MHz</li>"; echo "<li>核心数:{$CPUCores}</li>"; echo "</ul>"; ?>
如果需要更高效的缓存,可以改用Redis、Memcached等内存缓存工具,适合多用户共享数据的场景。
2. 调整远程PC的WMI连接超时设置
WMI连接的超时时间可以在远程Windows PC上配置,延长默认的超时阈值:
- 打开远程PC的「计算机管理」→「服务和应用程序」→「WMI控制」,右键选择「属性」
- 切换到「连接」选项卡,修改「超时」数值(比如设置为300秒=5分钟)
- 同时确保远程PC的防火墙允许WMI连接,且WMI服务(
Winmgmt)运行正常,避免连接被提前断开
3. 用常驻进程复用连接(进阶方案)
如果你的应用对性能要求较高,可以考虑使用常驻进程框架(如Workerman、Swoole)。在进程启动时一次性建立WMI连接,之后所有请求都复用这个连接,彻底避免重复建立连接的耗时。不过这种方案需要调整应用的部署架构,适合有一定开发经验的场景。
内容的提问来源于stack exchange,提问作者Mdarende
相关产品推荐
相关产品推荐

