websocket.JSON を使った場合
JSON をやりとりする場合専用の方法がある
(JSON-RPC ライクな実装を書いてみた場合)
package main
import (
"fmt"
"log"
"net/http"
"code.google.com/p/go.net/websocket"
)
type JSONRPCRequest struct {
Method string `json:"method"`
Params []interface{} `json:"params"`
Id uint `json:"id"`
}
type JSONRPCResponse struct {
Id uint `json:"id"`
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
type JSONRPCEventResponse struct {
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
func main() {
port := 51234
http.Handle("/", websocket.Handler(func(ws *websocket.Conn) {
log.Printf("New websocket: %v", ws)
var req JSONRPCRequest
for {
if err := websocket.JSON.Receive(ws, &req); err != nil {
break
}
log.Printf("Request: %v", req)
res := &JSONRPCResponse{Id: req.Id}
switch req.Method {
case "echo":
res.Result = req.Params
default:
res.Error = "unkown method"
}
log.Printf("Response: %v", res)
websocket.JSON.Send(ws, res)
}
log.Printf("Closed websocket: %v", ws)
}))
log.Printf("websocket server listen: %d", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
panic(err)
}
}
websocket.Message を使った場合
JSON だけやりとりするなら必要ないけどこのようにも書ける
- websocket.Message.Receive(ws, &in)
- websocket.Message.Send(ws, string(out))
をつかう。websocket.Message.Send の第2引数は byte[] だと JS 側では Blob を受けとれ、string だと JS 側では string を受けとれる。
バイナリを扱う場合、必然的にこちらをつかうことになる
同じことを冗長にやったコード
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"code.google.com/p/go.net/websocket"
)
type JSONRPCRequest struct {
Method string `json:"method"`
Params interface{} `json:"params"`
Id uint `json:"id"`
}
type JSONRPCResponse struct {
Id uint `json:"id"`
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
type JSONRPCEventResponse struct {
Result interface{} `json:"result"`
Error interface{} `json:"error"`
}
func main() {
port := 51234
http.Handle("/", websocket.Handler(func(ws *websocket.Conn) {
log.Printf("New websocket: %v", ws)
var in []byte
for {
if err := websocket.Message.Receive(ws, &in); err != nil {
break
}
log.Printf("Request: %s", in)
req := &JSONRPCRequest{}
json.Unmarshal(in, req)
res := &JSONRPCResponse{Id: req.Id}
switch req.Method {
case "echo":
res.Result = req.Params
default:
res.Error = "unkown method"
}
out, err := json.Marshal(res)
if err != nil {
panic(err)
}
log.Printf("Response: %s", out)
websocket.Message.Send(ws, string(out))
}
log.Printf("Closed websocket: %v", ws)
}))
log.Printf("websocket server listen: %d", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
panic(err)
}
}