富客户端应用的普遍流行,许多操作直接在客户端完成,而一些跟时间相关的操作, 客户端时间的正确性就显得尤为重要,一个和标准时间相差得离谱的时间, 可能会带来滑稽甚至严重的错误。
在C/S构架下,对时间有要求的应用程序一般解决方法是同步客户端和服务器端的时间, 一些要求较高的应用甚至需要专门的时间戳技术。
普通的B/S应用程序一般没有权限同步客户端的时间(也不一定有这个必要), 这个问题也有一些解决办法。
- 响应用户请求时返回服务器时间,并使用计时器(如:window.setInterval)做一个虚拟时钟。 但是考虑到浏览器消耗和脚本计时器本身并不精准,长时间运行后时钟会出现较大的误差,予以忽略。
- 响应用户请求时返回服务器时间,并计算服务器与客户端之间的时间差, 每次时间操作均以该差值进行修正(可以专门做一个接口)。或者考虑只有在 差值较大的情况下才进行修正(并提醒用户修正客户机时间)。
另外还要考虑用户所在不同时区的情况(Date.getTimezoneOffset)。
但是对于较精准的时间需求,这样仍然有一个问题,即从服务器端响应到客户端返回过程中 的网络传输时间。这是一个随机数,根据网络情况和其他偶然因素有关,从几十毫秒到几十秒不等, 有时达数分钟之久,最惨的是整个页面超时,当然同步也就没有必要了:)
如上图,客户端从客户机的t0时刻发送请求到服务端,然后服务端在T0时刻得到请求, 经过连接数据、计算等操作,最终在T1时刻响应完成,客户端最后在t1时刻加载完成。
此时我们最关心的是服务器返回到客户端加载完成这段时间的网络传输耗时,
但是暂时无法精确求得,只有一个相当不凑和方法:客户端发生请求时,
带上当时的客户机时间(t0,浏览器请求头信息里一般带有,也可以通过客户端脚本
new Date()
,此时则需要通过异步请求),服务器计算所耗时间也可以得到,
响应时返回服务器计算耗时(T1-T0)以及浏览器请求的时刻(t0)以及服务器时间,
客户端加载完成时刻(t1)计算网络传输总共耗时为:(t1-t1)-(T1-T0),
之后以一定比例(如1:1)计算响应的网络传输耗时。
结果相当不凑和,而过程又相当麻烦,所以只作为抛砖引玉之篇。
图片来自 Baidu图片 搜索。