Go言語 × AWSIoT × Raspberrypi やってみた


前の記事ではRaspberrypiとAWSIoTを通信させる時、サンプルのPythonプログラムで動かしました。
その際、他にも通信をする方法あるのかなと探してみたところ、Goでも出来そうだったので試してみることにしました。
記事自体は環境構築含めたメモ程度に。

参考ページ

以下のページを参考にしています。

golang+MQTTでAWS IoTにPubslish

Raspberry PiにGo言語をインストールする

AWS IoT × Raspberrypi でやったことメモ

Raspberrypi側でGo開発環境をセットアップ

Goをインストール。(任意のバージョンで)

$ wget https://storage.googleapis.com/golang/go1.9.linux-armv6l.tar.gz
$ sudo tar -C /usr/local -xzf go1.9.linux-armv6l.tar.gz

インストール確認とバージョン確認を行う。

$ ls -l /usr/local/go
$ cat /usr/local/go/VERSION

パスの追加。
~/.bashrcファイル末尾に以下を追記。

export PATH=$PATH:/usr/local/go/bin

設定したパスの確認

$ source .bashrc
$ echo $PATH
$ which go

必要ライブラリのインストール

$ go get github.com/eclipse/paho.mqtt.golang
$ go get golang.org/x/net/websocket
$ go get golang.org/x/net/proxy

ソースコード

今回はお試しなので、参照サイトのものをそのまま使用。
GoPath等の設定は任意で設定してください。
(今回は分かりやすいように、home直下に全ファイル置いた書き方をしています)

main.go

package main

import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"

    MQTT "github.com/eclipse/paho.mqtt.golang"
)

func NewTLSConfig() *tls.Config {
    // CA証明書を設定
    certpool := x509.NewCertPool()
    pemCerts, err := ioutil.ReadFile("xxxxxxxxx.pem")
    if err == nil {
        certpool.AppendCertsFromPEM(pemCerts)
    }

    // クライアント証明書とキーペアを設定
    cert, err := tls.LoadX509KeyPair("xxxxxxxxx-certificate.pem.crt", "xxxxxxxxx-private.pem.key")
    if err != nil {
        panic(err)
    }

    cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])
    if err != nil {
        panic(err)
    }

    // config設定
    return &tls.Config{

        RootCAs: certpool,
        ClientAuth: tls.NoClientCert,
        ClientCAs: nil,
        InsecureSkipVerify: true,
        Certificates: []tls.Certificate{cert},
    }
}

var f MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
    fmt.Printf("TOPIC: %s\n", msg.Topic())
    fmt.Printf("MSG: %s\n", msg.Payload())
}

func main() {
    tlsconfig := NewTLSConfig()

    opts := MQTT.NewClientOptions()
    opts.AddBroker("ssl://xxxxxxxxxxxxxxxxxxx.amazonaws.com:8883")
    opts.SetClientID("ssl-sample").SetTLSConfig(tlsconfig)
    opts.SetDefaultPublishHandler(f)

    // 接続をする
    c := MQTT.NewClient(opts)
    if token := c.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }
    fmt.Println("AWS IoT Connect Success")

    if token := c.Publish("$aws/things/ESP32/shadow/update", 0, false,
        `{"state":{"reported":{"welcome":"I am gopher!!!"}}}`); token.Wait() && token.Error() != nil {
                panic(token.Error())
    }
    fmt.Println("Message Publish Success")

    // 切断
    c.Disconnect(250)
}

実行結果

こんな感じで通信出来たみたいです。
Goは環境構築楽なので助かります。