我运行了几个游戏隧道服务器,希望有一个页面,客户端可以对所有服务器运行ping测试,并找出哪一个响应最快。据我所见,JavaScript似乎没有合适的方法来实现这一点,但我在想,是否有人知道如何在flash或其他客户端浏览器技术中实现这一点呢?
我运行了几个游戏隧道服务器,希望有一个页面,客户端可以对所有服务器运行ping测试,并找出哪一个响应最快。据我所见,JavaScript似乎没有合适的方法来实现这一点,但我在想,是否有人知道如何在flash或其他客户端浏览器技术中实现这一点呢?
大多数小程序技术,包括JavaScript,都实施了同源策略。可以通过使用onload事件处理程序动态添加DOM元素(例如图像)并收集时间信息。
伪代码:
for (server in servers) {
var img = document.createElement('IMG');
server.startTime = getCurrentTimeInMS();
img.onload=function() { server.endTime = getcurrentTimeInMS(); }
img.src = server.imgUrl;
}
然后等待适当的时间并检查每个服务器对象的时间。如果需要,请重复此操作并计算平均值。我不确定您可以期望什么样的准确性。
缺点:
var startTime = new Date();
从服务器加载图像:
var img = new Image()
img.onload = function() {
// record end time
}
img.src = "http://server1.domain.com/ping.jpg";
请求完成后,立即记录时间。(当然,假设请求没有超时。)
var endTime = new Date();
您的延迟为毫秒:
var ping = endTime. getTime() - startTime.getTime();
function getPing() { var start; var client = getClient(); // xmlhttprequest对象 client.onreadystatechange = function() { if (client.readyState > 0) { pingDone(start); //处理ping client.onreadystatechange = null; //移除处理程序 } }
start = new Date(); client.open("HEAD", "/ping.txt"); //静态文件 client.send(); }
function pingDone(start) { done = new Date(); ms = done.valueOf() - start.valueOf(); alert(ms + "毫秒的ping时间"); }
function getClient() { if (window.XMLHttpRequest) return new XMLHttpRequest();
if (window.ActiveXObject) return new ActiveXObject('MSXML2.XMLHTTP.3.0');
throw("没有可用的XMLHttpRequest对象."); }
<iframe>
的方法:
(来源:magnetiq.com)
创建一个表格(不一定是字面意义上的<table>
),其中包含两列。第一列将保存服务器名称(以及可能的链接)。第二列具有从相应服务器加载探针文档的 iframe。每个探针文档在初始获取请求时执行此操作:
您将使用iframe而不侵犯同域策略,因为根本没有尝试操纵iframe内容。播放器将仅仅通过眼睛看到值,您将依靠用户瞥一眼数字并点击最合适的服务器链接。
任何发起HTTP请求的操作(像大部分回答中提到的)通常会测量出至少是正常ping延迟两倍的延迟,因为你需要至少进行三次握手和终止数据包(而不是一次)(两个往返而不是一个)。如果你进行HTTP请求,请尽量减少头信息。由于服务器过于啰嗦或客户端上的cookie等,过长的头信息可能会增加额外的往返,从而影响你的测量结果。
正如Cherona所指出的,如果你已经与服务器建立了一个活动的HTTP 2连接,或者服务器使用HTTP 3协议,则情况可能不同。
最准确的选项是对每个服务器打开一个websocket连接,并测量发送微小消息并接收微小响应所需的时间(在连接建立后)。
如果你想在客户端运行某些东西,由于安全原因,我不确定这是否可能。
也许你最好的选择是使用Java小程序 - 但同样需要根据本地安全策略进行检查。
如果我试图考虑一些JS中的黑客技巧来做到这一点,也许你可以尝试发送一个异步请求,并使用回调函数来测量花费的毫秒数 - 但这只是我的想法。
在Flash中测量服务器响应时间并不难。
Flash在访问远程服务器之前必须请求策略文件。 这种策略文件的默认位置位于服务器的根目录下:/crossdomain.xml
(您可以轻松找到有关crossdomain文件格式的信息)
既然无论如何都需要这样的文件,为什么不使用它来测量服务器响应时间呢?用getTimer()加载文件本身并测量所需的时间即可。
这将为您提供有关HTTP连接的良好估计。
但是,如果您处理游戏服务器,则可能希望直接检查TCP连接的速度。为此,您需要使用flash.net.Socket 您还需要先运行以下命令请求策略文件: Security.loadPolicyFile("xmlsocket://server.domain.com:5342");
其中5342表示服务器端口号,服务器应该以正确的XML策略字符串进行响应。 建立套接字连接后,任何请求/响应都将让您测量不同的服务器响应时间。
根据 @Mr. Shiny 和 @Georg Schölly 的回复,这里提供了一个完整且有注释的例子。
为了测试,请按照以下顺序将代码复制并粘贴到空的 .html、.php 或其他兼容文件中。
在开始获取之前,记录当前的 JavaScript 时间。
使用 new Date()
,我们创建一个新的日期对象,其中包含当前的日期和时间。
<script type="text/javascript">
var startTime = new Date();
var img = new Image();
var random_string = Math.random().toString();
img.src = "http://static.bbci.co.uk/frameworks/barlesque/5.0.0/orb/4/img/bbc-blocks-dark.png" + "?" + random_string;
img.onload = function() {
var endTime = new Date();
var ping = endTime. getTime() - startTime.getTime();
alert(img.src + " loaded in " + ping + " ms");
}
</script>
在函数内部,我们有一个变量endTime,它接收源图像加载后的日期时间。
最后,ping变量接收初始时间减去最终时间。警告弹出窗口显示结果。