みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Goを使ってウェブサーバを立て、ブラウザ上のボタンを押した際に電球を光らせる 💡

最近、Goを勉強し始めたので、試しに電球を光らせることのできるウェブサイトを作ってみようと思います。
なぜならば「光るのGo」と名付けたいからです。


Goは初心者ですが、DMXを制御できるライブラリを見つけたので、これを使えばサクッと実装できるのではないかと思っています。
github.com

❶ Goのインストール

https://go.dev/dl/ よりインストールしました。

Node.jsではanyenvとnodenvを使ってバージョンを切り替えているので、Goもバージョン切り替え用に、なにかツール経由でインストールした方が良いのかな?と思いましたが、普通にバージョンの切り替えが可能みたいなので、普通に導入しました。

go.dev

brew install go

で入れようかとも思ったのですが、公式に従った次第です。

❷ プロジェクトの作成・初期化

mkdir shining-go
cd shining-go
go mod init github.com/username/appname

❸ コードを書く

main.go

package main

import (
  "encoding/json"
  "log"
  "net/http"
  "time"
  "github.com/akualab/dmx"
)

var timer *time.Timer

func shining() {
  dmx, err := dmx.NewDMXConnection("/dev/tty.usbserial-EN437503") // ポートを合わせる
  if err != nil {
    log.Fatal(err)
  }

  dmx.SetChannel(2, 100) // チャンネルを合わせる
  dmx.Render()

  if timer != nil {
    timer.Stop()
  }

  timer = time.AfterFunc(1*time.Second, func() {
    dmx.SetChannel(2, 0)
    dmx.Render()
    dmx.Close()
  })
}

func shiningGetHandler(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")

  switch r.Method {
  case http.MethodGet:
    response := struct {
      Message string `json:"message"`
    } {
      Message: "GET",
    }

    json.NewEncoder(w).Encode(response)

    case http.MethodPost:
    response := struct {
      Message string `json:"message"`
    } {
      Message: "POST",
    }

    shining()
    json.NewEncoder(w).Encode(response)
  }
}

func main() {
	fs := http.FileServer(http.Dir("./public"))

	http.Handle("/", fs)
  http.HandleFunc("/api/shining", shiningGetHandler)

	port := ":8080"
	err := http.ListenAndServe(port, nil)
	if err != nil {
		log.Fatal(err)
	}
}

まだ、初めてのGo言語を読んだぐらいの知識ですが、
:= が便利ですね。

switch文はswitchとcaseにインデントをつけないのが、やや気持ち悪いと思ってしまうのと、brakeがないのが新鮮です。

public/index.html

<html>
  <head>
    <meta charset="UTF-8">
    <title>Shining Go</title>
    <style>
      body {
        display: flex;
        align-items: center;
        justify-content: center;
        position: fixed;
        inset: 0;
      }

      button {
        font-size: 32px;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <button>💡</button>
    <script>
      document.querySelector('button').addEventListener('click', () => {
        fetch('/api/shining', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          }
        }).then((evt) => {
          console.log(evt);
        });
      });
    </script>
  </body>
</html>

CSSもJSもHTMLに直書きしました。

❹ ライブラリを追加

go get github.com/akualab/dmx
go mod tidy 

❻ 実行

go run main.go

ブラウザに表示された「ヒカル」ボタンを押すと1秒ぐらい電球が光ります。「光るのGo」です。

実装手順が適切なのかは、ちょっとわからないので、間違っているところがあれば随時訂正していこうと思います。

リポジトリ

github.com