来源:
Introduction - robomq.iohttps://robomq.readthedocs.io/en/latest/MQTT/#go
Go
Prerequisite 预先准备
The Go library we use for this example can be found at https://eclipse.org/paho/clients/golang/. Its GitHub repository is at GitHub - eclipse/paho.mqtt.golang.
You can install it through go get github.com/eclipse/paho.mqtt.golang
.
Finally, import this library in your program.
这个例子里使用的Go库,在这儿
https://eclipse.org/paho/clients/golang/. 它的GitHub 源代码仓库在GitHub - eclipse/paho.mqtt.golang.
安装库 go get github.com/eclipse/paho.mqtt.golang
.
然后,在自己的代码里引用之
import MQTT "github.com/eclipse/paho.mqtt.golang"
The full documentation of this library is at https://godoc.org/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git.
This library depends on Google's websockets package, which is installed with
go get golang.org/x/net/websocket
关于这个库的使用说明,参考 https://godoc.org/git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git.
这个库还依赖谷歌的 websockets 包
go get golang.org/x/net/websocke
Producer生产者
The first thing we need to do is to establish a connection with the RoboMQ broker.
RoboMQ allows you to specify vhost along with username. See Vhost specification section for the detail.
Set keep alive to 60 seconds, so that client will confirm the connectivity with broker.
Although the library provides an AutoReconnect
connection option, we discourage you to use it. The reason will be explained in the Consumer section.
我们要做的第一件事情,是跟RoboMQ 代理 创建一个链接。
RoboMQ允许你设定主机,用户名。
保持在线60秒,这可以让客户端跟客户确认连接。
虽然这个库提供了一个AutoReconnect 自动重连的连接选项,我们不建议使用(可以在消费者 章节找到理由)
connOpts := MQTT.NewClientOptions().AddBroker(fmt.Sprintf("tcp://%s:%d", server, port))
connOpts.SetUsername(fmt.Sprintf("%s:%s", vhost, username))
connOpts.SetPassword(password)
connOpts.SetClientID("0")
connOpts.SetCleanSession(true)
connOpts.SetKeepAlive(60 * time.Second)
connOpts.SetAutoReconnect(false)
client := MQTT.NewClient(connOpts)
client.Connect()
After that, producer can send messages to a particular topic.
The second parameter is QoS, third is boolean flag for retain.
然后,生产者就可以给某个特定主题发送消息了。
第一个参数:主题
第二个参数:Qos等级( 参考MQTT 协议中的 QoS 等级 MQTT QoS 设计:车联网平台消息传输质量保障-51CTO.COM),
第三个:是否维持(布尔参数)
client.Publish(topic, 1, false, message)
At last, producer will disconnect with the RoboMQ broker.
The parameter 250
is the number of milliseconds to wait for existing work to be completed.
最后,生产者会断开链接。 等待250毫秒,确保现有工作完成。
client.Disconnect(250)
Consumer 消费者
The first step is the same as producer, consumer needs to connect to the RoboMQ broker.
As we mentioned in the Producer section, AutoReconnect
is set to false when connecting to the RoboMQ broker. It matters for consumers because AutoReconnect
will only recover the connection, it won't resubscribe the topics. Therefore, a more robust approach is letting your code handle reconnecting and resubscribing on its own.
第一步和生产者类似,消费者也需要连接到RoboMQ代理。正如我们在生产者那一章提到过的,AutoReconnect 自动重连设置为否。因为AutoReconnect 自动重连仅仅覆盖连接,它不会重新订阅主题。因此,一个更健壮的做法是让你的代码处理自动重连和自己重新订阅。
The next step is to subscribe a topic, so that consumer knows where to listen to. The second argument in subscribe()
function is QoS, the third one is the callback function to handle incoming messages.
下一步是订阅一个主题,让消费者知道听啥消息。
client.Subscribe(topic, 1, OnMessage)
Once it receives a message from the queue bound by the topic, it will trigger the callback function onMessage()
to print the topic and message payload.
一旦它从主题绑定的某个队列收到消息,就会出发回调函数 onMessage() 打印主题和消息有效负载。
var OnMessage MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
fmt.Printf("Topic: %s, Message: %s\n", msg.Topic(), msg.Payload())
}
When you no longer need it, you can also unsubscribe a topic.
如果不再需要,也可以取消订阅某个主题
client.Unsubscribe(topic)
代码整合
package main
import (
"fmt"
MQTT "github.com/eclipse/paho.mqtt.golang"
"os"
"time"
)
var server = "hostname"
var port = 1883
var vhost = "yourvhost"
var username = "username"
var password = "password"
var topic = "test/any"
func main() {
connOpts := MQTT.NewClientOptions().AddBroker(fmt.Sprintf("tcp://%s:%d", server, port))
connOpts.SetUsername(fmt.Sprintf("%s:%s", vhost, username))
connOpts.SetPassword(password)
connOpts.SetClientID("1")
connOpts.SetCleanSession(true)
connOpts.SetKeepAlive(60 * time.Second)
connOpts.SetAutoReconnect(false)
// Create and start a client using the above ClientOptions
client := MQTT.NewClient(connOpts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
fmt.Printf("Failed to connect, err: %v\n", token.Error())
os.Exit(1)
}
var msgNum int
fmt.Print("Quantity of test messages: ")
fmt.Scanf("%d", &msgNum)
for i := 0; i < msgNum; i++ {
message := fmt.Sprintf("test msg %d", i+1)
// QoS = 1, retained = false
token := client.Publish(topic, 1, false, message)
// Use PublishToken to confirmed receipt from the broker
token.Wait()
if token.Error() != nil {
fmt.Printf("Failed to publish, err: %v\n", token.Error())
os.Exit(1)
}
time.Sleep(time.Second)
}
client.Disconnect(250)
}
consumer.go
package main
import (
"fmt"
MQTT "github.com/eclipse/paho.mqtt.golang"
"time"
)
var server = "hostname"
var port = 1883
var vhost = "yourvhost"
var username = "username"
var password = "password"
var topic = "test/#"
/**
* This function is the callback on receiving messages.
* @ It prints the message topic and payload on console.
*/
var OnMessage MQTT.MessageHandler = func(client MQTT.Client, msg MQTT.Message) {
fmt.Printf("Topic: %s, Message: %s\n", msg.Topic(), msg.Payload())
}
func main() {
connOpts := MQTT.NewClientOptions().AddBroker(fmt.Sprintf("tcp://%s:%d", server, port))
connOpts.SetUsername(fmt.Sprintf("%s:%s", vhost, username))
connOpts.SetPassword(password)
connOpts.SetClientID("0")
connOpts.SetCleanSession(true)
connOpts.SetKeepAlive(60 * time.Second)
connOpts.SetAutoReconnect(false)
// Infinite loop to auto-reconnect on failure
for {
// Create and start a client using the above ClientOptions
client := MQTT.NewClient(connOpts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
fmt.Printf("Failed to connect, err: %v\n", token.Error())
}
// QoS = 1
if token := client.Subscribe(topic, 1, OnMessage); token.Wait() && token.Error() != nil {
fmt.Printf("Failed to subscribe, err: %v\n", token.Error())
}
// Constantly checking connectivity
for client.IsConnected() {
time.Sleep(time.Second)
}
fmt.Println("Restarting in 5 seconds...")
time.Sleep(5 * time.Second)
}
}