Server
The fully compliant, embeddable high-performance Go MQTT v5 server for IoT, smarthome, and pubsub
Install / Use
/learn @mochi-mqtt/ServerREADME
Mochi-MQTT Server
<p align="center"> </p>English | 简体中文 | 日本語 | Translators Wanted!
🎆 mochi-co/mqtt is now part of the new mochi-mqtt organisation. Read about this announcement here.
Mochi-MQTT is a fully compliant, embeddable high-performance Go MQTT v5 (and v3.1.1) broker/server
Mochi MQTT is an embeddable fully compliant MQTT v5 broker server written in Go, designed for the development of telemetry and internet-of-things projects. The server can be used either as a standalone binary or embedded as a library in your own applications, and has been designed to be as lightweight and fast as possible, with great care taken to ensure the quality and maintainability of the project.
What is MQTT?
MQTT stands for MQ Telemetry Transport. It is a publish/subscribe, extremely simple and lightweight messaging protocol, designed for constrained devices and low-bandwidth, high-latency or unreliable networks (Learn more). Mochi MQTT fully implements version 5.0.0 of the MQTT protocol.
Mochi-MQTT Features
- Full MQTTv5 Feature Compliance, compatibility for MQTT v3.1.1 and v3.0.0:
- User and MQTTv5 Packet Properties
- Topic Aliases
- Shared Subscriptions
- Subscription Options and Subscription Identifiers
- Message Expiry
- Client Session Expiry
- Send and Receive QoS Flow Control Quotas
- Server-side Disconnect and Auth Packets
- Will Delay Intervals
- Plus all the original MQTT features of Mochi MQTT v1, such as Full QoS(0,1,2), $SYS topics, retained messages, etc.
- Developer-centric:
- Most core broker code is now exported and accessible, for total developer control.
- Full-featured and flexible Hook-based interfacing system to provide easy 'plugin' development.
- Direct Packet Injection using special inline client, or masquerade as existing clients.
- Performant and Stable:
- Our classic trie-based Topic-Subscription model.
- Client-specific write buffers to avoid issues with slow-reading or irregular client behaviour.
- Passes all Paho Interoperability Tests for MQTT v5 and MQTT v3.
- Over a thousand carefully considered unit test scenarios.
- TCP, Websocket (including SSL/TLS), and $SYS Dashboard listeners.
- Built-in Redis, Badger, Pebble and Bolt Persistence using Hooks (but you can also make your own).
- Built-in Rule-based Authentication and ACL Ledger using Hooks (also make your own).
Compatibility Notes
Because of the overlap between the v5 specification and previous versions of mqtt, the server can accept both v5 and v3 clients, but note that in cases where both v5 an v3 clients are connected, properties and features provided for v5 clients will be downgraded for v3 clients (such as user properties).
Support for MQTT v3.0.0 and v3.1.1 is considered hybrid-compatibility. Where not specifically restricted in the v3 specification, more modern and safety-first v5 behaviours are used instead - such as expiry for inflight and retained messages, and clients - and quality-of-service flow control limits.
When is this repo updated?
Unless it's a critical issue, new releases typically go out over the weekend.
Roadmap
- Please open an issue to request new features or event hooks!
- Cluster support.
- Enhanced Metrics support.
Quick Start
Running the Broker with Go
Mochi MQTT can be used as a standalone broker. Simply checkout this repository and run the cmd/main.go entrypoint in the cmd folder which will expose tcp (:1883), websocket (:1882), and dashboard (:8080) listeners.
cd cmd
go build -o mqtt && ./mqtt
Using Docker
You can now pull and run the official Mochi MQTT image from our Docker repo:
docker pull mochimqtt/server
or
docker run -v $(pwd)/config.yaml:/config.yaml mochimqtt/server
For most use cases, you can use File Based Configuration to configure the server, by specifying a valid yaml or json config file.
A simple Dockerfile is provided for running the cmd/main.go Websocket, TCP, and Stats server, using the allow-all auth hook.
docker build -t mochi:latest .
docker run -p 1883:1883 -p 1882:1882 -p 8080:8080 -v $(pwd)/config.yaml:/config.yaml mochi:latest
File Based Configuration
You can use File Based Configuration with either the Docker image (described above), or by running the build binary with the --config=config.yaml or --config=config.json parameter.
Configuration files provide a convenient mechanism for easily preparing a server with the most common configurations. You can enable and configure built-in hooks and listeners, and specify server options and compatibilities:
listeners:
- type: "tcp"
id: "tcp12"
address: ":1883"
- type: "ws"
id: "ws1"
address: ":1882"
- type: "sysinfo"
id: "stats"
address: ":1880"
hooks:
auth:
allow_all: true
options:
inline_client: true
Please review the examples found in examples/config for all available configuration options.
There are a few conditions to note:
- If you use file-based configuration, the supported hook types for configuration are currently limited to auth, storage, and debug. Each type of hook can only have one instance.
- You can only use built in hooks with file-based configuration, as the type and configuration structure needs to be known by the server in order for it to be applied.
- You can only use built in listeners, for the reasons above.
If you need to implement custom hooks or listeners, please do so using the traditional manner indicated in cmd/main.go.
Developing with Mochi MQTT
Importing as a package
Importing Mochi MQTT as a package requires just a few lines of code to get started.
import (
"log"
mqtt "github.com/mochi-mqtt/server/v2"
"github.com/mochi-mqtt/server/v2/hooks/auth"
"github.com/mochi-mqtt/server/v2/listeners"
)
func main() {
// Create signals channel to run server until interrupted
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigs
done <- true
}()
// Create the new MQTT Server.
server := mqtt.New(nil)
// Allow all connections.
_ = server.AddHook(new(auth.AllowHook), nil)
// Create a TCP listener on a standard port.
tcp := listeners.NewTCP(listeners.Config{ID: "t1", Address: ":1883"})
err := server.AddListener(tcp)
if err != nil {
log.Fatal(err)
}
go func() {
err := server.Serve()
if err != nil {
log.Fatal(err)
}
}()
// Run server until interrupted
<-done
// Cleanup
}
Examples of running the broker with various configurations can be found in the examples folder.
Network Listeners
The server comes with a variety of pre-packaged network listeners which allow the broker to accept connections on different protocols. The current listeners are:
| Listener | Usage | |------------------------------|----------------------------------------------------------------------------------------------| | listeners.NewTCP | A TCP listener | | listeners.NewUnixSock | A Unix Socket listener | | listeners.NewNet | A net.Listener listener | | listeners.NewWebsocket | A Websocket listener | | listeners.NewHTTPStats | An HTTP $SYS info dashboard | | listeners.NewHTTPHealthCheck | An HTTP healthcheck listener to provide health check responses for e.g. cloud infrastructure |
Use the
listeners.Listenerinterface to develop new listeners. If you do, please let us know!
A *listeners.Config may be passed to configure TLS.
Examples of usage can be found in the examples folder or cmd/main.go.
Server Options and Capabilities
A number of configurable options are available which can be used to alter the behaviour or restrict access to certain features in the server.
server := mqtt.New(&mqtt.Options{
Capabilities: mqtt.Capabilities{
MaximumSessionExpiryInterval: 3600,
MaximumClientWritesPending: 3,
Compatibilities: mqtt.Compatibilities{
ObscureNotAuthorized: true,
},
},
ClientNetWriteBufferSize: 4096,
ClientNetReadBufferSize: 4096,
SysTopicResendInterval: 10,
InlineClient: false,
})
Review the mqtt.Options, mqtt.Capabilities, and mqtt.Compatibilities structs
