英文:
appengine dev_appserver time strangeness
问题
我是新来的Google AppEngine和Go和Web堆栈,所以很可能我在这里做错了什么,但我无法弄清楚:)
我正在尝试用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 -
我在下面粘贴了我的代码(使用pastebin更好吗?)。
干杯!
Brad
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 = `
`
英文:
I'm new to Google AppEngine & to Go & to Web stacks - so it is very likely something I'm doing wrong here, but I can't figure it out
I'm trying to write a simple clock app in Go where the the server pushes to the client & a JS handler updates an HTML element. I'm using the TaskQueue api to reschedule the server side update, and I've changed the default queue frequency to be once per second. The server sends a payload string that contains the number of times the task URL has been hit & the current time. The hit count updates at a rate of 1 per second, as expected - but the time stamp barely changes. The log output I'm seeing in the dev_appserver console looks correct
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 -
I've pasted my code below (is a pastebin better?).
Cheers!
Brad
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>
`
答案1
得分: 2
- 开发服务器的队列和时间行为与生产服务器的行为完全不同(在时间上)。
- 依赖队列来提供一个恒定且稳定的定时器中断是一个非常糟糕的想法。
英文:
- The dev_server queue and timing behaves nothing like how the production server behaves (timing wise).
- It is a very bad idea to depend on the queue to give you a constat and stable timer interup.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论