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>
`