■ 環境
release: "1.7.4"timestamp: 1352314290
api_versions: ['go1']
■ 概要
■今回作成したプロジェクトhttps://github.com/mogeta/golang_channelAPI_example
■ドキュメント
https://developers.google.com/appengine/docs/go/channel/
を試してみようと思ったのですが、コードの中に微妙な間違い
(×:ParseFile ◯:ParseFiles)http://golang.org/pkg/html/template/
等があったりし、思ったよりも四苦八苦したので
最もシンプルな形で動作するサンプルを書いてみました。
とりあえず、ローカルで動いたので一旦commit
■ ChannelAPIとは
GAEが提供している機能の一つでWebsocketのような機能を提供してくれます。ポーリング等をせずとも、いわゆるリアルタイムな通信を可能にしてくれます。
たとえば、チャットや、ネットゲーム等で使うことができるのではないでしょうか。
■ Github
プロジェクトは一式、Githubの方に展開致しました。シンプルに動作確認することだけを目指したので、ChannelAPIで接続し、
自分にメッセージを返すだけの簡単なアプリケーションになっています
https://github.com/mogeta/golang_channelAPI_example
■ スクリーンショット
■ 説明
Go側のチャネル作成tok, err := channel.Create(c, u.ID+key)チャネルを作成します。「u.ID+key」によって個人を識別するkeyを作成しています。
javascript側のチャネル作成
var channel = new goog.appengine.Channel( {{.token}} );
javascript側はGolangのテンプレートモジュールによって埋め込まれた{{.token}}からチャネルトークンを受け取り
channelオブジェクトを作成しています。ボタンを押した際、javascript側から/receiveを叩きに行き、
go側はfunc receive(w http.ResponseWriter, r *http.Request)でそれを受け取り
channel.Sendを叩く。という形になっています。
以下、ソースコード(2013/03/05) channel.go
package channelExample
import (
"html/template"
"net/http"
"time"
"appengine"
"appengine/channel"
"appengine/user"
)
func init() {
http.HandleFunc("/", main)
http.HandleFunc("/receive", receive)
}
var mainTemplate = template.Must(template.ParseFiles("channel/main.html"))
func main(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
u := user.Current(c) // assumes 'login: required' set in app.yaml
key := r.FormValue("gamekey")
tok, err := channel.Create(c, u.ID+key)
if err != nil {
http.Error(w, "Couldn't create Channel", http.StatusInternalServerError)
c.Errorf("channel.Create: %v", err)
return
}
err = mainTemplate.Execute(w, map[string]string{
"token": tok,
"me": u.ID,
"game_key": key,
})
if err != nil {
c.Errorf("mainTemplate: %v", err)
}
}
func receive(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
key := r.FormValue("g")
channel.Send(c, key, "go receive!"+time.Now().String())
}
main.html
<html>
<body>
<form action="#">
<input type="button" value="OK" onclick="return exe()">
</form>
<div id="area"></div>
<script type="text/javascript" src="/_ah/channel/jsapi"></script>
<script>
var channel = new goog.appengine.Channel( {{.token}} );
var socket = channel.open({
onopen : function(){
document.getElementById("area").innerHTML+="{{.token}} ::: onopen<br />";
}
, onmessage : function(message) {
document.getElementById("area").innerHTML+="onmessage::"+message.data+"<br />";
}
, onerror : function(error) {
document.getElementById("area").innerHTML+="onerror<br />";
}
, onclose : function(){
document.getElementById("area").innerHTML+="onclose<br />";
}
});
</script>
<script>
function exe() {
var path = '/receive?g=' + {{.me}} + {{.game_key}} ;
var xhr = new XMLHttpRequest();
xhr.open('POST', path, true);
xhr.send();
}
</script>
</body>
</html>
0 件のコメント :
コメントを投稿