用go语言实现在中移动OneNet的MQTT交互
发送方
代码中的设备密钥
、产品ID
、设备ID
都可以在后台管理系统里查询到
package main
import (
"crypto/tls"
"fmt"
MQTT "github.com/eclipse/paho.mqtt.golang"
"math/rand"
"time"
)
const qos = 0
const server = "tcp://183.230.40.39:6002"
const topic = "sample/data"
const password = "设备密钥"
const username = "产品ID"
const clientid = "设备ID"
func main() {
connOpts := MQTT.NewClientOptions().AddBroker(server).SetClientID(clientid).SetCleanSession(true)
connOpts.SetUsername(username)
connOpts.SetPassword(password)
tlsConfig := &tls.Config{InsecureSkipVerify: true, ClientAuth: tls.NoClientCert}
connOpts.SetTLSConfig(tlsConfig)
client := MQTT.NewClient(connOpts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
fmt.Println(token.Error())
return
}
fmt.Printf("Connected to %s\n", server)
for {
message := fmt.Sprintf("{\"data\":\"%v\", \"time\":\"%v\"}", rand.Intn(10000), time.Now().Format("2006-01-02 15:04:05"))
fmt.Printf("MQTT SENDER: %s\n", message)
client.Publish(topic, byte(qos), false, message)
time.Sleep(5 * time.Second)
}
}
接收方
package main
import (
"crypto/tls"
MQTT "github.com/eclipse/paho.mqtt.golang"
"log"
"os"
"os/signal"
"syscall"
)
const qos = 0
const server = "tcp://183.230.40.39:6002"
const password = "设备密钥"
const username = "产品ID"
const clientid = "设备ID"
var onMessageReceived MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
log.Printf("MQTT RECEIVER: topic: %s Message: %s\n", msg.Topic(), msg.Payload())
}
func main() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
sub_topics := []string{
"sample/data",
}
connOpts := MQTT.NewClientOptions().AddBroker(server).SetClientID(clientid).SetCleanSession(true)
connOpts.SetUsername(username)
connOpts.SetPassword(password)
tlsConfig := &tls.Config{InsecureSkipVerify: true, ClientAuth: tls.NoClientCert}
connOpts.SetTLSConfig(tlsConfig)
connOpts.SetDefaultPublishHandler(onMessageReceived)
client := MQTT.NewClient(connOpts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
log.Println(token.Error())
return
}
log.Printf("Connected to %s\n", server)
for _, topic := range sub_topics {
if token := client.Subscribe(topic, byte(qos), nil); token.Wait() && token.Error() != nil {
log.Println(token.Error())
return
}
}
<-c
}
API的Token算法
其中productID
、accessKey
可以在产品管理页面查到,expiry
是过期时间戳
func getAPIToken(productID int, accessKey string, expiry int64) string {
const method = "sha256"
const version = "2018-10-31"
res := fmt.Sprintf("products/%v", productID)
et := fmt.Sprintf("%v", expiry)
signature := et + "\n" + method + "\n" + res + "\n" + version
key, _ := base64.StdEncoding.DecodeString(accessKey)
mac := hmac.New(sha256.New, key)
mac.Write([]byte(signature))
sign := base64.StdEncoding.EncodeToString(mac.Sum(nil))
res = url.QueryEscape(res)
sign = url.QueryEscape(sign)
s := fmt.Sprintf("version=%v&res=%v&et=%v&method=%v&sign=%v",
version, res, et, method, sign)
return s
}