Jos*_*unt 23 javascript time synchronization
我正在使用精彩的reveal.js库来创建HTML幻灯片.我唯一的问题是我需要它来跨多个设备进行同步.
目前我正在从服务器发出一个AJAX请求,并保留页面的内部时钟.
function syncTime() {
// Set up our time object, synced by the HTTP DATE header
// Fetch the page over JS to get just the headers
console.log("syncing time")
var r = new XMLHttpRequest();
r.open('HEAD', document.location, false);
r.send(null);
var timestring = r.getResponseHeader("DATE");
systemtime = new Date(timestring); // Set the time to the date sent from the server
}
Run Code Online (Sandbox Code Playgroud)
虽然这让我在1秒左右的准确度,但我需要做得更好.幻灯片显示自动前进时,差异非常明显.
代码将在同一平台上运行,因此跨浏览器兼容性无需担心.
有任何想法吗?
Mik*_*att 22
测量发送请求和返回响应之间经过的时间.然后,将该值除以2.这为您提供了单向延迟的粗略值.如果将其添加到服务器的时间值,您将更接近真实的服务器时间.
这样的事情应该有效:
function syncTime() {
// Set up our time object, synced by the HTTP DATE header
// Fetch the page over JS to get just the headers
console.log("syncing time")
var r = new XMLHttpRequest();
var start = (new Date).getTime();
r.open('HEAD', document.location, false);
r.onreadystatechange = function()
{
if (r.readyState != 4)
{
return;
}
var latency = (new Date).getTime() - start;
var timestring = r.getResponseHeader("DATE");
// Set the time to the **slightly old** date sent from the
// server, then adjust it to a good estimate of what the
// server time is **right now**.
systemtime = new Date(timestring);
systemtime.setMilliseconds(systemtime.getMilliseconds() + (latency / 2))
};
r.send(null);
}
Run Code Online (Sandbox Code Playgroud)
有趣的是:John Resig有一篇关于Javascript计时准确性的文章.
在这种情况下它不应该引起问题,因为你只关心你的休息时间约1秒钟.15毫秒的差异不应该有太大的影响.
jos*_*736 19
不同的方法怎么样:谁在乎时间?(您不会使用JavaScript可靠地同步系统时钟.)
而是在客户端推进幻灯片放映时使用带有socket.io的节点服务器进行同步.服务器告诉他们,而不是客户决定何时前进.
这种方法带来了额外的好处,即能够在幻灯片运行时手动摆弄幻灯片.在下面的示例中,我添加了一个Next按钮,使所有连接的客户端立即前进到下一张幻灯片.
var express = require('express')
, app = express.createServer()
, io = require('socket.io').listen(app)
, doT = require('dot')
, slide = 0
, slides = [
'http://placekitten.com/700/400?image=13',
'http://placekitten.com/700/400?image=14',
'http://placekitten.com/700/400?image=15',
'http://placekitten.com/700/400?image=16',
'http://placekitten.com/700/400?image=1',
'http://placekitten.com/700/400?image=2',
'http://placekitten.com/700/400?image=3',
'http://placekitten.com/700/400?image=4',
'http://placekitten.com/700/400?image=5',
'http://placekitten.com/700/400?image=6',
'http://placekitten.com/700/400?image=7',
'http://placekitten.com/700/400?image=8',
'http://placekitten.com/700/400?image=9',
'http://placekitten.com/700/400?image=10',
'http://placekitten.com/700/400?image=11',
'http://placekitten.com/700/400?image=12',
];
app.listen(70); // listen on port 70
app.register('.html', doT); // use doT to render templates
app.set('view options', {layout:false}); // keep it simple
doT.templateSettings.strip=false; // don't strip line endings from template file
app.get('/', function(req, res) {
res.render('index.html', { slide: slide, slides: slides });
});
app.post('/next', function(req, res) {
next();
res.send(204); // No Content
});
setInterval(next, 4000); // advance slides every 4 seconds
function next() {
if (++slide >= slides.length) slide = 0;
io.sockets.emit('slide', slide);
}
Run Code Online (Sandbox Code Playgroud)
此文件作为doT模板处理.
<!DOCTYPE html>
<html>
<head>
<title>Synchronized Slideshow</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var curslide = {{=it.slide}}; // the slide the server is currently on.
$(function() {
$('#slide' + curslide).css('left',0);
$('#next').click(function() {
$.post('/next');
});
});
var socket = io.connect('http://localhost:70');
socket.on('slide', function(slide) {
$('#slide' + curslide).animate({left:-700}, 400);
$('#slide' + slide).css('left',700).show().animate({left:0}, 400);
curslide = slide;
});
</script>
<style>
#slideshow, .slide { width:700px; height:400px; overflow:hidden; position:relative; }
.slide { position:absolute; top:0px; left:700px; }
</style>
</head>
<body>
<div id="slideshow">
{{~it.slides :url:i}}
<div id="slide{{=i}}" class="slide"><img src="{{=url}}"></div>
{{~}}
</div>
<button id="next">Next ></button>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
将这两个文件复制到一个文件夹中,然后运行
$ npm install express socket.io dot
$ node app.js
Run Code Online (Sandbox Code Playgroud)
并导航到http://localhost:70几个不同的窗口,然后看到魔术.
Dav*_*aun 11
我很高兴你找到了一个满意的答案.我有类似的需要将浏览器与服务器的时钟同步,并决心以超过1秒的精度实现它,就像你一样.我已编写代码来执行此操作,并在此处发布此答案,以防其他人也需要解决方案.
该代码称为ServerDate,可免费下载.这是自述文件的一部分.请注意,在我的示例中,我达到了108 ms的精度:
您可以ServerDate像使用Date函数或其中一个实例一样使用,例如:
> ServerDate()
"Mon Aug 13 2012 20:26:34 GMT-0300 (ART)"
> ServerDate.now()
1344900478753
> ServerDate.getMilliseconds()
22
Run Code Online (Sandbox Code Playgroud)
还有一种新方法可以获得ServerDate估计服务器时钟的精度(以毫秒为单位):
> ServerDate.toLocaleString() + " ± " + ServerDate.getPrecision() + " ms"
"Tue Aug 14 01:01:49 2012 ± 108 ms"
Run Code Online (Sandbox Code Playgroud)
您可以看到服务器的时钟和浏览器时钟之间的差异,以毫秒为单位:
> ServerDate - new Date()
39
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12070 次 |
| 最近记录: |