覚えたら書く

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

Go言語 - melodyを利用してWebSocketサーバを立てる

melodyGinを使ってWebSocketサーバを立てて、簡易的なチャット画面を作ってみました。

実際には、melody Exampleを、ほぼそのまま流用しているだけです。


準備

以下を実行してmelodyを利用可能な状態にしておきます

go get gopkg.in/olahol/melody.v1


プログラムとhtml

WebSocketサーバと動作確認用チャット画面のindex.htmlとして以下を用意しました。

■WebSocketサーバ(Goプログラム)

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/gin-gonic/gin"
    "gopkg.in/olahol/melody.v1"
)

func main() {
    log.Println("Websocket App start.")

    router := gin.Default()
    m := melody.New()

    rg := router.Group("/sampleapp")
    rg.GET("/", func(ctx *gin.Context) {
        http.ServeFile(ctx.Writer, ctx.Request, "index.html")
    })

    rg.GET("/ws", func(ctx *gin.Context) {
        m.HandleRequest(ctx.Writer, ctx.Request)
    })

    m.HandleMessage(func(s *melody.Session, msg []byte) {
        m.Broadcast(msg)
    })

    m.HandleConnect(func(s *melody.Session) {
        log.Printf("websocket connection open. [session: %#v]\n", s)
    })

    m.HandleDisconnect(func(s *melody.Session) {
        log.Printf("websocket connection close. [session: %#v]\n", s)
    })

    // Listen and server on 0.0.0.0:8989
    router.Run(":8989")

    fmt.Println("Websocket App End.")
}


■index.html

<html>
  <head>
    <title>Chat powered by Melody</title>
  </head>

  <style>
    #chat {
      text-align: left;
      color:#ffffff;
      background: #113131;
      width: 400px;
      min-height: 300px;
      padding: 10px;
      font-family: 'Lucida Grande', 'Hiragino Kaku Gothic ProN', 'ヒラギノ角ゴ ProN W3', 'Meiryo', 'メイリオ', sans-serif;
      font-size: small;
    }
  </style>

  <body>

    <center>
      <h3>Sample Chat</h3>
      <pre id="chat"></pre>
      <label id="title"></label>
      <input placeholder="say something" id="text" type="text">
    </center>

    <script>
      var url = "ws://" + window.location.host + "/sampleapp/ws";
      var ws = new WebSocket(url);
      var name = "Guest-" + Math.floor(Math.random() * 1000);
      var chat = document.getElementById("chat");
      document.getElementById("title").innerText = name + ": ";
      
      var text = document.getElementById("text");
      var now = function () {
        return new Date().toLocaleString();
      };

      ws.onmessage = function (msg) {
        var line =  now() + " : " + msg.data + "\n";
        chat.innerText += line;
      };

      text.onkeydown = function (e) {
        if (e.keyCode === 13 && text.value !== "") {
          ws.send("[" + name + "] > " + text.value);
          text.value = "";
        }
      };
    </script>

  </body>
</html>


実行してみた

対象のアプリを実行します。実行すると以下のようなログがコンソールに出力されます

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /sampleapp/               --> main.main.func1 (3 handlers)
[GIN-debug] GET    /sampleapp/ws             --> main.main.func2 (3 handlers)
[GIN-debug] Listening and serving HTTP on :8989


http://localhost:8989/sampleapp/にアクセスすることでチャット画面が利用できました


f:id:nini_y:20170523160815g:plain


というわけで、お遊び程度ですがかなりコード量少なくWebSocketのサーバサイドを実装することができました。



関連エントリ