Feature rich modern MQTT library in pure Go, for Go
, C/C++
, Java
Notice: This is a fork of https://github.com/goiiot/libmqtt that has been roughly patched to correctly handle packets from mqtt 3.1 and mqtt 5. The parent branch does not allow 3.1 and has mostly empty mqtt 5 tests and has completely broken mqtt5. (atw)
- MQTT v3.1.1/v5.0 client support (async only)
- High performance and less memory footprint (see Benchmark)
- Customizable topic routing (see Topic Routing)
- Multiple Builtin session persist methods (see Session Persist)
- C/C++ lib, Java lib, Command line client support
- Idiomatic Go
This package can be used as
- Go 1.9+
TL;DR: You can find a full example at examples/client.go
1.Go get this project
go get github.com/goiiot/libmqtt
2.Import this package in your project file
import "github.com/goiiot/libmqtt"
3.Create a custom client
// Create a client and enable auto reconnect when connection lost
// We primarily use `RegexRouter` for client
client, err := libmqtt.NewClient(
// enable keepalive (10s interval) with 20% tolerance
libmqtt.WithKeepalive(10, 1.2),
// enable auto reconnect and set backoff strategy
libmqtt.WithAutoReconnect(true),
libmqtt.WithBackoffStrategy(time.Second, 5*time.Second, 1.2),
// use RegexRouter for topic routing if not specified
// will use TextRouter, which will match full text
libmqtt.WithRouter(libmqtt.NewRegexRouter()),
)
if err != nil {
// handle client creation error
panic("create mqtt client failed")
}
Notice: If you would like to explore all the options available, please refer to GoDoc#Option
4.Register the handlers and Connect, then you are ready to pub/sub with server
Optional, but we recommend to register handlers for pub, sub, unsub, net error and persist error, and you can gain more controllability of the lifecycle of the client
client.HandlePub(PubHandler) // register handler for pub success/fail (optional, but recommended) client.HandleSub(SubHandler) // register handler for sub success/fail (optional, but recommended) client.HandleUnSub(UnSubHandler) // register handler for unsub success/fail (optional, but recommended) client.HandleNet(NetHandler) // register handler for net error (optional, but recommended) client.HandlePersist(PersistHandler) // register handler for persist error (optional, but recommended)
// define your topic handlers like a golang http server client.Handle("foo", func(topic string, qos libmqtt.QosLevel, msg []byte) { // handle the topic message })
client.Handle("bar", func(topic string, qos libmqtt.QosLevel, msg []byte) { // handle the topic message })
// connect to server
client.ConnectServer("test.mosquitto.org:8883",
libmqtt.WithCustomTLS(nil),
libmqtt.WithConnHandleFunc(func(server string, code byte, err error) {
if err != nil {
// failed
panic(err)
}
if code != libmqtt.CodeSuccess {
// server rejected or in error
panic(code)
}
// success
// you are now connected to the `server`
// (the `server` is one of your provided `servers` when create the client)
// start your business logic here or send a signal to your logic to start
// subscribe some topic(s)
client.Subscribe([]*libmqtt.Topic{
{Name: "foo"},
{Name: "bar", Qos: libmqtt.Qos1},
}...)
// publish some topic message(s)
client.Publish([]*libmqtt.PublishPacket{
{TopicName: "foo", Payload: []byte("bar"), Qos: libmqtt.Qos0},
{TopicName: "bar", Payload: []byte("foo"), Qos: libmqtt.Qos1},
}...)
}),
)
5.Unsubscribe from topic(s)
client.UnSubscribe("foo", "bar")
6.Destroy the client when you would like to
// use true for a immediate disconnect to server
// use false to send a DisConn packet to server before disconnect
client.Destroy(true)
Please refer to c - README.md
Please refer to java - README.md
Please refer to cmd/libmqtt - README.md
This package can also be used as MQTT packet encoder and decoder
// decode one mqtt 3.1.1 packet from reader
packet, err := libmqtt.Decode(libmqtt.V311, reader)
// ...
// encode one mqtt packet to buffered writer
err := libmqtt.Encode(packet, bufferedWriter)
// ...
Routing topics is one of the most important thing when it comes to business logic, we currently have built two TopicRouter
s which is ready to use, they are TextRouter
and RegexRouter
TextRouter
will match the exact same topic which was registered to client byHandle
method. (this is the default router in a client)RegexRouter
will go through all the registered topic handlers, and use regular expression to test whether that is matched and should dispatch to the handler
If you would like to apply other routing strategy to the client, you can provide this option when creating the client
client, err := libmqtt.NewClient(
// ...
// e.g. use `RegexRouter`
libmqtt.WithRouter(libmqtt.NewRegexRouter()),
// ...
)
Per MQTT Specification, session state should be persisted and be recovered when next time connected to server without clean session flag set, currently we provide persist method as following:
NonePersist
- no session persistmemPersist
- in memory session persistfilePersist
- files session persist (with write barrier)redisPersist
- redis session persist (available inside github.com/goiiot/libmqtt/extension package)
Note: Use RedisPersist
if possible.
The procedure of the benchmark is:
- Create the client
- Connect to server
- Publish N times to topic
foo
- Unsubscribe topic (just ensure all pub message has been sent)
- Destroy client (without disconnect packet)
The benchmark result listed below was taken on a MacBook Pro 13' (Early 2015, macOS 10.13.2), statistics inside which is the value of ten times average
Bench Name | Pub Count | ns/op | B/op | allocs/op |
---|---|---|---|---|
BenchmarkLibmqttClient-4 (this project) | 100000 | 20187 | 176 | 6 |
BenchmarkPahoClient-4 (eclipse paho) | 100000 | 25072 | 816 | 15 |
You can make the benchmark using source code from benchmark
Helpful extensions for libmqtt (see extension)
Copyright Go-IIoT (https://github.com/goiiot)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.