Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine appengine dev_appserver时间奇怪性_Google App Engine_Go - Fatal编程技术网

Google app engine appengine dev_appserver时间奇怪性

Google app engine appengine dev_appserver时间奇怪性,google-app-engine,go,Google App Engine,Go,我是谷歌AppEngine的新手,我不太熟悉网络栈,所以我很可能在这里做错了什么,但我想不出来:) 我试图在Go中编写一个简单的时钟应用程序,服务器将时钟推送到客户端&一个JS处理程序更新一个HTML元素。我正在使用TaskQueue api重新安排服务器端更新,并将默认队列频率更改为每秒一次。服务器发送一个有效负载字符串,其中包含任务URL被命中的次数&当前时间。命中计数以每秒1次的速度更新,正如预期的那样-但是时间戳几乎没有变化。我在dev_appserver控制台中看到的日志输出看起来是正

我是谷歌AppEngine的新手,我不太熟悉网络栈,所以我很可能在这里做错了什么,但我想不出来:)

我试图在Go中编写一个简单的时钟应用程序,服务器将时钟推送到客户端&一个JS处理程序更新一个HTML元素。我正在使用TaskQueue api重新安排服务器端更新,并将默认队列频率更改为每秒一次。服务器发送一个有效负载字符串,其中包含任务URL被命中的次数&当前时间。命中计数以每秒1次的速度更新,正如预期的那样-但是时间戳几乎没有变化。我在dev_appserver控制台中看到的日志输出看起来是正确的

INFO     2012-07-05 03:04:31,955 dev_appserver.py:2952] "POST /update HTTP/1.1" 200 -
INFO     2012-07-05 03:04:31,985 dev_appserver.py:2952] "POST /update HTTP/1.1" 200 -
INFO     2012-07-05 03:04:32,015 dev_appserver.py:2952] "POST /update HTTP/1.1" 200 -
INFO     2012-07-05 03:04:32,043 dev_appserver.py:2952] "POST /update HTTP/1.1" 200 -
我已经在下面粘贴了我的代码(粘贴箱更好吗?)

干杯! 布拉德

包时钟
进口(
“fmt”
“阿彭金”
“appengine/频道”
“appengine/数据存储”
“appengine/taskqueue”
“html/模板”
“net/http”
“时间”
//“应用程序/用户”
)
类型问候语结构{
作者字符串
内容字符串
日期时间,时间
}
func init(){
http.HandleFunc(“/”,根)
http.HandleFunc(“/update”,update)
}
类型TemplateFiller结构{
时间串
令牌串
}
var clientId string=“clockclient”
func root(w http.ResponseWriter,r*http.Request){
c:=appengine.NewContext(r)
q:=datastore.NewQuery(“问候”).Order(“日期”).Limit(10)
问候语:=make([]问候语,0,10)
如果,err:=q.GetAll(c,&问候语); err!=nil{
Error(w,err.Error(),http.StatusInternalServerError)
返回
}
token,u:=channel.Create(c,clientId);
tf:=TemplateFiller{time.Now().String(),token}
如果错误:=guestbookTemplate.Execute(w,tf);错误!=nil{
Error(w,err.Error(),http.StatusInternalServerError)
}
重新安排(c)
}
func重新调度(c appengine.Context){
t:=taskqueue.NewPOSTTask(“/update”,map[string][]string{“token”:{clientId})
如果389;,err:=taskqueue.Add(c,t,“”);err!=nil{
返回
}
}
var命中int=0
func更新(w http.ResponseWriter,r*http.Request){
c:=appengine.NewContext(r)
Send(c,clientId,fmt.Sprintln(hits)+time.Now().Format(time.rfc339))
点击次数=点击次数+1
//Send(c,clientId,time.Now().Format(time.rfc339))
重新安排(c)
}
var guestbookTemplate=template.Must(template.New(“”).Parse(guestbookTemplateHTML))
const guestbookTemplateHTML=`
没时间
$(文档).ready(函数(){
onMessage=函数(msg){
$(“#timediv”).html(msg.data);
}
channel=new goog.appengine.channel('{.Token}');
socket=channel.open();
//socket.onopen=onOpened;
socket.onmessage=onmessage;
//socket.onerror=onerror;
//socket.onclose=onclose;
});
`
  • dev_服务器队列和计时的行为与生产服务器的行为完全不同(按计时)
  • 依靠队列为您提供一个常量和稳定的计时器中断是一个非常糟糕的主意

  • 谢谢你的回复!1.我使用time.Now().String()来获取时间,当然服务器的时间戳来自操作系统&应该是正确的。2.我并不期望任务队列提供的不仅仅是定期更新。我并不打算在生产中使用这种东西,但我的第一个测试应用程序显示了一些非常奇怪的行为。
    package clock
    
    import (
        "fmt"
        "appengine"
        "appengine/channel"
        "appengine/datastore"
        "appengine/taskqueue"
        "html/template"
        "net/http"
        "time"
    //  "appengine/user"
    )
    
    type Greeting struct {
        Author  string
        Content string
        Date    time.Time
    }
    
    func init() {
        http.HandleFunc("/", root)
        http.HandleFunc("/update", update)
    }
    
    type TemplateFiller struct {
        Time      string
        Token     string
    }
    
    var clientId string = "clockclient"
    
    func root(w http.ResponseWriter, r *http.Request) {
        c := appengine.NewContext(r)
        q := datastore.NewQuery("Greeting").Order("-Date").Limit(10)
        greetings := make([]Greeting, 0, 10)
        if _, err := q.GetAll(c, &greetings); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
    
        token, _ := channel.Create(c, clientId);
        tf := TemplateFiller{time.Now().String(), token}
    
        if err := guestbookTemplate.Execute(w, tf); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
        }
    
        reschedule(c)
    }
    
    func reschedule(c appengine.Context) {
        t := taskqueue.NewPOSTTask("/update", map[string][]string{"token": {clientId}})
            if _, err := taskqueue.Add(c, t, ""); err != nil {
                return
            }
    }
    
    var hits int = 0
    
    func update(w http.ResponseWriter, r *http.Request) {
        c := appengine.NewContext(r)
        channel.Send(c, clientId, fmt.Sprintln(hits) + time.Now().Format(time.RFC3339))
        hits = hits + 1
        //channel.Send(c, clientId, time.Now().Format(time.RFC3339))
        reschedule(c)
    }
    
    var guestbookTemplate = template.Must(template.New("").Parse(guestbookTemplateHTML))
    
    const guestbookTemplateHTML = `
    <html>
      <script type="text/javascript" src="/_ah/channel/jsapi"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
      <body>
    <div id="timediv">No time</div>
    
    <script type="text/javascript">
    $(document).ready(function(){
    
       onMessage = function(msg) {
          $("#timediv").html(msg.data);
       }
    
        channel = new goog.appengine.Channel('{{.Token}}');
        socket = channel.open();
        //socket.onopen = onOpened;
        socket.onmessage = onMessage;
        //socket.onerror = onError;
        //socket.onclose = onClose;
     });
    
    </script>
    
      </body>
    </html>
    `