11

使用 Meteor,在显示服务器时间的客户端上保持运行时钟 (h:m:s) 的有效方法是什么?

我发现的 JavaScript/PHP 答案通常涉及定期获取服务器时间并计算该时间与客户端之间的差异。

Meteor 会是什么样子?

更新:自从我最初发布这个问题以来,发生了很多变化。如果您对预先构建的解决方案感兴趣,我建议您查看 @mizzao 的Meteor Timesyncmeteor add mizzao:timesync通过在控制台中运行来安装它。

4

5 回答 5

21

David Greenspan在 14:30 左右在 Spark 上的这个演示文稿中获得了客户时间。我稍微修改了这段代码以获得服务器端时间:

Javascript:

if (Meteor.isClient) {
    Meteor.startup(function () {
        setInterval(function () {
            Meteor.call("getServerTime", function (error, result) {
                Session.set("time", result);
            });
        }, 1000);
    });

    Template.main.time = function () {
        return Session.get("time");
    };
}

if (Meteor.isServer) {
    Meteor.methods({
        getServerTime: function () {
            var _time = (new Date).toTimeString();
            console.log(_time);
            return _time;
        }
    });
}

和 HTML:

<body>
  {{> main}}
</body>

<template name="main">
  {{time}}
</template>
于 2013-01-09T01:03:12.580 回答
8

关于这个线程有很好的信息。我已经将所有内容整合到 Meteor 的智能包中:

https://github.com/mizzao/meteor-timesync

除了已经在这里的内容之外,我还添加了两个主要内容:

  • 使用 NTP 风格的数学更准确地计算服务器/客户端偏移量,而不是仅仅区分客户端和服务器时间并忽略往返时间。
  • 能够反应性地使用服务器时间戳来显示将在模板和反应性计算中自我更新的值。

随意打开拉取请求,特别是如果您有更好/更有效的方法来计算和维护偏移量的想法。

于 2014-03-11T17:59:30.360 回答
6

感谢@TimDog 的帮助。我对该代码进行了一些扩展,以便仅定期检查服务器,同时仍然在客户端上显示正在运行的时钟。这就是我最终的结果:

客户端代码:

  Meteor.startup(function () {

    function setServerTime(){

      //get server time (it's in milliseconds)
      Meteor.call("getServerTime", function (error, result) {

        //get client time in milliseconds
        localTime = new Date().getTime();

        //difference between server and client
        var serverOffset = result - localTime;

        //store difference in the session
        Session.set("serverTimeOffset", serverOffset);

      });
    }

    function setDisplayTime(){
      var offset = Session.get("serverTimeOffset");
      var adjustedLocal = new Date().getTime() + offset;
      Session.set("serverTime", adjustedLocal);
    }

    //run these once on client start so we don't have to wait for setInterval
    setServerTime();
    setDisplayTime();

    //check server time every 15min
    setInterval(function updateServerTime() {
      setServerTime();
    }, 900000);

    //update clock on screen every second
    setInterval(function updateDisplayTime() {
      setDisplayTime();
    }, 1000);

  });

  //pass the clock to the HTML template
  Template.register.clock = function () {
    return new Date(Session.get("serverTime"));
  };

服务器代码:

Meteor.methods({

    //get server time in milliseconds
    getServerTime: function () {
        var _time = (new Date).getTime();
        console.log(_time);
        return _time;
    }

  });
于 2013-01-10T01:59:26.513 回答
0

作为这个问题的后续,这是性能消耗吗?我们每秒都在计算偏移量,并根据这个重新计算来改变会话。

这是否意味着任何其他依赖于 Session 的东西也会每秒重新计算一次?

设置成别的东西会更好吗?

或者简单地制作一个根据需要进行本地日期调整的方法,而不是设置间隔和会话变量。

让我知道你发现了什么。

于 2013-04-22T06:38:53.510 回答
0

只需订阅一个普通的集合并将您的日期放入其中:(无往返计算)

import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';

export const ServerDate = new Mongo.Collection(null);

if (Meteor.isServer) {
  // This code only runs on the server
  Meteor.publish('serverDate', function serverDatePublication() {
    return ServerDate.find({});
  });
  console.log('<ServerDate>:', new Date());
  Meteor.setInterval(updateDate, 1000 * 1);
}

function updateDate() {
  // Clean out result cache
  ServerDate.remove({});
  ServerDate.insert(new Date());
}
于 2018-03-21T20:29:40.913 回答