2024-08-31
MQTT over websocketの通信のkeepaliveを見る
サーバ mochi/serverのwebsocket exampleを使う https://github.com/mochi-mqtt/server/tree/main/examples/websocket
クライアントはpahoを使う https://github.com/eclipse/paho.mqtt.golang
ソースコードは下記の改変 https://qiita.com/emqx_japan/items/31472d22e9a2cad36dd8
package main
import (
"fmt"
"log"
"os"
"time"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
fmt.Println("Connected")
}
var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
fmt.Printf("Connect lost: %v", err)
}
func main() {
mqtt.ERROR = log.New(os.Stdout, "[ERROR] ", 0)
mqtt.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0)
mqtt.WARN = log.New(os.Stdout, "[WARN] ", 0)
mqtt.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0)
var broker = "192.168.0.100"
var port = 1882
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("ws://%s:%d", broker, port))
opts.SetDefaultPublishHandler(messagePubHandler)
opts.OnConnect = connectHandler
opts.OnConnectionLost = connectLostHandler
opts.KeepAlive = 5
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
time.Sleep(time.Second * 120)
}
WebSocket
1... .... = Fin: True
.000 .... = Reserved: 0x0
.... 0010 = Opcode: Binary (2)
1... .... = Mask: True
.000 1110 = Payload length: 14
Masking-Key: 2299147f
Masked payload
Payload
Data (14 bytes)
Data: 100c00044d515454040200050000
[Length: 14]
Websocketの形式でMaskされており、中身は10から始まる。1はMQTT fixed HeaderのConnectを示している。
Client -> Host
WebSocket
1... .... = Fin: True
.000 .... = Reserved: 0x0
.... 0010 = Opcode: Binary (2)
1... .... = Mask: True
.000 0010 = Payload length: 2
Masking-Key: 75e2bbfd
Masked payload
Payload
Data (2 bytes)
Data: c000
[Length: 2]
cはPINGREQ
Host -> Client
WebSocket
1... .... = Fin: True
.000 .... = Reserved: 0x0
.... 0010 = Opcode: Binary (2)
0... .... = Mask: False
.000 0010 = Payload length: 2
Payload
Data (2 bytes)
Data: d000
[Length: 2]
dはPINGRESP
MQTT Headerについては下記のリンクを参照 https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718020