読者です 読者をやめる 読者になる 読者になる

覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。 twitter: @yyoshikaw

Go言語 - WebSocketのクライアントでJSONメッセージをやり取りしてみる

golang.org/x/net/websocketパッケージでWebSocketクライアント側の実装サンプルです。
(WebSocketサーバ側は別に存在していて、クライアントから送られたメッセージオウム返しするEchoServerになっているものとします)


■サンプルコード

大まかに、websocket.DialでWebSocketのクライアントを生成してコネクション確立し、websocket.Connを通じてメッセージの送受信を行うという流れになっています。

実際に送受信するメッセージはJSON形式として、websocket.JSON.Sendでサーバへのメッセージ送信、websocket.JSON.Receiveでサーバからのメッセージ受信を行います

package main

import (
    "log"
    "time"

    "golang.org/x/net/websocket"
)

var (
    origin = "http://localhost:8787/"
    url    = "ws://localhost:8787/echo"
)

// EchoMsg is Sample Websocket Message
type EchoMsg struct {
    Msg string // メッセージ
    ID  int32  // ID
}

func main() {
    ws, err := websocket.Dial(url, "", origin)
    if err != nil {
        log.Fatal(err)
    }

    go receiveMsg(ws)

    sendMsg(ws, "Hello", 1)
    sendMsg(ws, "Goodbye", 2)

    time.Sleep(1 * time.Second)
    _ = ws.Close()

    defer log.Printf("Web Socket Client Sample end.")
}

func sendMsg(ws *websocket.Conn, msg string, id int32) {
    var sndMsg = EchoMsg{msg, id}

    websocket.JSON.Send(ws, sndMsg)
    log.Printf("Send data=%#v\n", sndMsg)
}

func receiveMsg(ws *websocket.Conn) {
    var rcvMsg EchoMsg
    for {
        websocket.JSON.Receive(ws, &rcvMsg)
        log.Printf("Receive data=%#v\n", rcvMsg)
    }
}

sendMsgがサーバへメッセージ送信をする部分で、receiveMsgでサーバからのメッセージを受信している部分になります。
(サーバからのメッセージを全て受信するために1秒だけスリープしています。あまり本質的なものではありません)


■実行結果

上記サンプルの実行結果は以下の通りです

2017/04/24 05:55:09 Send data=main.EchoMsg{Msg:"Hello", ID:1}
2017/04/24 05:55:09 Receive data=main.EchoMsg{Msg:"Hello", ID:1}
2017/04/24 05:55:09 Send data=main.EchoMsg{Msg:"Goodbye", ID:2}
2017/04/24 05:55:09 Receive data=main.EchoMsg{Msg:"Goodbye", ID:2}
2017/04/24 05:55:10 Web Socket Client Sample end.

無事にWebSocketサーバとメッセージの送受信ができました



補足

本エントリのサンプルでは、コネクションが切れた場合の再接続処理など考慮しなければならない点が諸々抜けています。
(Go言語歴がまだ浅い私が書いたサンプルですので、ご注意ください)


今回利用したgolang.org/x/net/websocket以外にもgorilla/websocketといったWebSocketのライブラリも存在しているようです。
こちらの方がかなり機能が豊富なようです