外部package、websocket - GoDoc を使います。
下記は、bitflyerのAPIを使用して、BTCとJPYの取引をリアルタイムに取得する例です。
type JsonRPC2 struct { // JSON-RPCのプロトコルをtype定義
Version string `json:"version"`
Method string `json:"method"`
Params interface{} `json:"params"`
Result interface{} `json:"result"`
ID *int `json:"id"`
}
type SubscribeParams struct { // bitflyerのJSON-RPCプロトコルが、名前付き引数("channel")での利用を想定して設計されているため、別途typeを定義
Channel string `json:"channel"`
}
func main() {
u := url.URL{Scheme: "wss", Host: "ws.lightstream.bitflyer.com", Path: "/json-rpc"} // bitflyer公式の案内に従う
log.Printf("connecting to %s", u.String()) // どこに接続したのかが分かるよう、最初にログ出力(ログのため、時間が分かる)
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) // websocketによる接続を確立
if err != nil {
log.Fatalln("dial:", err)
}
defer c.Close() // 最後に接続を閉じる
// JSON形式で送信。プロトコルは、bitflyer公式の案内に従う
if err := c.WriteJSON(&JsonRPC2{Version: "2.0", Method: "subscribe", Params: SubscribeParams{Channel: "lightning_ticker_BTC_JPY"}}); err != nil {
log.Fatalln("write:", err)
}
c.SetWriteDeadline(time.Now().Add(10 * time.Second)) // 10秒以内に送信が成功できない場合、エラーを返す
for {
message := new(JsonRPC2)
if err := c.ReadJSON(message); err != nil { // JSON形式で受信。プロトコルは、定義したJsonRPC2
log.Fatalln("read:", err)
}
c.SetReadDeadline(time.Now().Add(10 * time.Second)) // 10秒以内に受信が成功できない場合、エラーを返す
if message.Method == "channelMessage" { // bitflyer公式の案内に従う
log.Println(message.Params)
}
}
}
送信、受信共にDeadlineの指定は必須です。
Deadlineの指定がなく、プロトコルの中身に間違いがあった場合、
応答がないまま、待ち続けることになります。