获得我的世界服务器状态的最佳方法 - 查询,流套接字......?

Posted

技术标签:

【中文标题】获得我的世界服务器状态的最佳方法 - 查询,流套接字......?【英文标题】:Best way to get a minecraft servers status - query, stream_socket...? 【发布时间】:2013-10-31 06:35:12 【问题描述】:

前段时间我使用查询来检查我的世界服务器的状态。 php,但我对结果并不满意。有时只用了 10 多秒,甚至没有得到状态,尽管 mc 服务器已启动且网络服务器位于同一数据中心内。

您认为哪种方法最稳定且性能最佳:query、stream_stocket 还是其他方法?

我应该每 30 秒运行一次测试吗?一个 cronjob 或只是将结果缓存 30 秒'?

【问题讨论】:

就个人而言,我使用socket_sendto()socket_readfrom(),因为您不需要连接到套接字来发送/接收请求。您可以尝试使用 memcached 将结果存储 x 秒,然后在数据过期时再次存储。 @BenFortune 嗨,我从来没有在 socket_sendto() 和 socket_readfrom() 工作过,你会这么好心,告诉我你是怎么做的吗?与 query 或 stream_stocket_client 相比,您认为它以这种方式工作更稳定、性能更好吗? 【参考方案1】:

您可以使用此代码创建一个 PHP 文件并定期运行以存储状态。

<?php
/**
 * @author Kristaps Karlsons <kristaps.karlsons@gmail.com>
 * Licensed under MPL 1.1
 */

function mc_status($host,$port='25565') 
    $timeInit = microtime();
    // TODO: implement a way to store data (memcached or mysql?) - please don't overload target server
    $fp = fsockopen($host,$port,$errno,$errstr,$timeout=10);
    if(!$fp) die($errstr.$errno);
    else 
        fputs($fp, "\xFE"); // xFE - get information about server
        $response = '';

        while(!feof($fp)) $response .= fgets($fp);
        fclose($fp);
        $timeEnd = microtime();

        $response = str_replace("\x00", "", $response); // remove NULL

        //$response = explode("\xFF", $response); // xFF - data start (old version, prior to 1.0?)
        $response = explode("\xFF\x16", $response); // data start

        $response = $response[1]; // chop off all before xFF (could be done with regex actually)

        //echo(dechex(ord($response[0])));
        $response = explode("\xA7", $response); // xA7 - delimiter

        $timeDiff = $timeEnd-$timeInit;
        $response[] = $timeDiff < 0 ? 0 : $timeDiff;
    
    return $response;


$data = mc_status('mc.exs.lv','25592'); // even better - don't use hostname but provide IP instead (DNS lookup is a waste)

print_r($data); // [0] - motd, [1] - online, [2] - slots, [3] - time of request (in microseconds - use this to present latency information)

致谢:skakri (https://gist.github.com/skakri/2134554)

【讨论】:

谢谢,但问题是哪种方式最快(资源使用率最低)而不是如何。 ;) @user2693017 这个脚本非常快。这里花了 1 秒。

以上是关于获得我的世界服务器状态的最佳方法 - 查询,流套接字......?的主要内容,如果未能解决你的问题,请参考以下文章

处理一百万个并发套接字连接的最佳方法

使用以下查询获得结果的最佳方法是啥

socket编程

如何使gRPC 获得最佳性能?

用于本地客户端-服务器通信的套接字与标准流

设置套接字流不起作用