Categorygithub.com/cfeeling/mqtt
module
1.0.6
Repository: https://github.com/cfeeling/mqtt.git
Documentation: pkg.go.dev

# README

Build Status contributions welcome codecov Codacy Badge GoDoc

Mochi MQTT

A High-performance MQTT server in Go (v3.0 | v3.1.1)

Mochi MQTT is an embeddable high-performance MQTT broker server written in Go, and compliant with the MQTT v3.0 and v3.1.1 specification for the development of IoT and smarthome projects. The server can be used either as a standalone binary or embedded as a library in your own projects. Mochi MQTT message throughput is comparable with everyone's favourites such as Mosquitto, Mosca, and VerneMQ.

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 Features

  • Paho MQTT 3.0 / 3.1.1 compatible.
  • Full MQTT Feature-set (QoS, Retained, $SYS)
  • Trie-based Subscription model.
  • Ring Buffer packet codec.
  • TCP, Websocket, (including SSL/TLS) and Dashboard listeners.
  • Interfaces for Client Authentication and Topic access control.
  • Bolt-backed persistence and storage interfaces.

Roadmap

  • Inline Pub-sub (without client) and event hooks
  • Docker Image
  • MQTT v5 compatibility

Performance (messages/second)

Performance benchmarks were tested using MQTT-Stresser on a 13-inch, Early 2015 Macbook Pro (2.7 GHz Intel Core i5). Taking into account bursts of high and low throughput, the median scores are the most useful. Higher is better. SEND = Publish throughput, RECV = Subscribe throughput.

As usual, any performance benchmarks should be taken with a pinch of salt, but are shown to demonstrate typical throughput compared to the other leading MQTT brokers.

Single Client, 10,000 messages With only 1 client, there is no variation in throughput so the benchmark is reports the same number for high, low, and median.

1 Client, 10,000 Messages

mqtt-stresser -broker tcp://localhost:1883 -num-clients=1 -num-messages=10000

MochiMosquittoEMQXVerneMQMosca
SEND Max3650530597272023278230125
SEND Min3650530597272023278230125
SEND Median3650530597272023278230125
RECV Max152221591307879175519145
RECV Min152221591307879175519145
RECV Median152221591307879175519145

10 Clients, 1,000 Messages

10 Clients, 1,000 Messages

mqtt-stresser -broker tcp://localhost:1883 -num-clients=10 -num-messages=1000

MochiMosquittoEMQXVerneMQMosca
SEND Max3719315775174553413836575
SEND Min65296446771485837383
SEND Median1512778131030598878169
RECV Max335353710302245349411
RECV Min74842661168920212275
RECV Median114273142183124684692

10 Clients, 10,000 Messages

10 Clients, 10000 Messages

mqtt-stresser -broker tcp://localhost:1883 -num-clients=10 -num-messages=10000

MochiMosquittoEMQXVerneMQMosca
SEND Max1315313270122291302538446
SEND Min87288513819364833889
SEND Median90459532925280319210
RECV Max2077450522093207143008
RECV Min1071839951531167318764
RECV Median1633946071620190733524

500 Clients, 100 Messages

500 Clients, 100 Messages

mqtt-stresser -broker tcp://localhost:1883 -num-clients=500 -num-messages=100

MochiMosquittoEMQXVerneMQMosca
SEND Max7068872686713927533673192
SEND Min10212577160384172344
SEND Median4987133076336373520031312
RECV Max11616342153427548410100
RECV Min10441565683169
RECV Median2439820894413474

Using the Broker

Mochi MQTT can be used as a standalone broker. Simply checkout this repository and run the main.go entrypoint in the cmd folder which will expose tcp (:1883), websocket (:1882), and dashboard (:8080) listeners. A docker image is coming soon.

cd cmd
go build -o mqtt && ./mqtt

Quick Start

import (
    mqtt "github.com/cfeeling/mqtt/server"
)

func main() {
    // Create the new MQTT Server.
    server := mqtt.New()
    
    // Create a TCP listener on a standard port.
    tcp := listeners.NewTCP("t1", ":1883")
    
    // Add the listener to the server with default options (nil).
    err := server.AddListener(tcp, nil)
	if err != nil {
		log.Fatal(err)
	}
	
	// Start the broker. Serve() is blocking - see examples folder 
	// for usage ideas.
    err = server.Serve()
	if err != nil {
		log.Fatal(err)
	}
}

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:

  • listeners.NewTCP(id, address string) - A TCP Listener, taking a unique ID and a network address to bind.
  • listeners.NewWebsocket(id, address string) A Websocket Listener
  • listeners.NewHTTPStats() An HTTP $SYS info dashboard
Configuring Network Listeners

When a listener is added to the server using server.AddListener, a *listeners.Config may be passed as the second argument.

Authentication and ACL

Authentication and ACL may be configured on a per-listener basis by providing an Auth Controller to the listener configuration. Custom Auth Controllers should satisfy the auth.Controller interface found in listeners/auth. Two default controllers are provided, auth.Allow, which allows all traffic, and auth.Disallow, which denies all traffic.

    err := server.AddListener(tcp, &listeners.Config{
		Auth: new(auth.Allow),
	})

If no auth controller is provided in the listener configuration, the server will default to Disallowing all traffic to prevent unintentional security issues.

SSL

SSL may be configured on both the TCP and Websocket listeners by providing a public-private PEM key pair to the listener configuration as []byte slices.

    err := server.AddListener(tcp, &listeners.Config{
		Auth: new(auth.Allow),
		TLS: &listeners.TLS{
			Certificate: publicCertificate, 
			PrivateKey:  privateKey,
		},
	})

Note the mandatory inclusion of the Auth Controller!

Data Persistence

Mochi MQTT provides a persistence.Store interface for developing and attaching persistent stores to the broker. The default persistence mechanism packaged with the broker is backed by Bolt and can be enabled by assigning a *bolt.Store to the server.

    // import "github.com/cfeeling/mqtt/server/persistence/bolt"
err = server.AddStore(bolt.New("mochi.db", nil))
	if err != nil {
		log.Fatal(err)
	}

Persistence is on-demand (not flushed) and will potentially reduce throughput when compared to the standard in-memory store. Only use it if you need to maintain state through restarts.

Paho Interoperability Test

You can check the broker against the Paho Interoperability Test by starting the broker using examples/paho/main.go, and then running the test with python3 client_test.py from the interoperability folder.

Contributions

Contributions and feedback are both welcomed and encouraged! Open an issue to report a bug, ask a question, or make a feature request.

# Packages

No description provided by the author
No description provided by the author
packet server provides a MQTT 3.1.1 compliant MQTT server.