goqtt

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2020 License: MIT Imports: 9 Imported by: 1

README

Build Go Report Card PkgGoDev

goqtt

goqtt is a simple MQTT client library. It is intended for lightweight MQTT applications where security and data guarantees are not important (see limitations below).


Install

Using go 1.13 or higher, install using go modules:

go get github.com/andschneider/goqtt

Usage

subscription

Below is a simple example showing a subscription to a specified topic. Any Publish message received on the topic will be returned, allowing for further processing if desired. Note: there is no error handling in the example, which is not advised.

package main

import (
	"log"

	"github.com/andschneider/goqtt"
)

func main() {
	// Create Client
	topic := goqtt.Topic("goqtt")
	client := goqtt.NewClient("mqtt.eclipse.org", topic)

	// Attempt a connection to the specified MQTT broker
	client.Connect()
	defer client.Disconnect()

	// Attempt to subscribe to the topic
	client.Subscribe()

	// Read messages indefinitely
	for {
		log.Println("waiting for message")
		m, _ := client.ReadLoop()
		if m != nil {
			log.Printf("received message: '%s' from topic: '%s'", string(m.Message), m.Topic)
		}
	}
}
publish

Below is a simple example showing how to Publish a message to a specified topic. Note: there is no error handling in the example, which is not advised.

package main

import (
	"log"

	"github.com/andschneider/goqtt"
)

func main() {
	// Create Client
	topic := goqtt.Topic("goqtt")
	client := goqtt.NewClient("mqtt.eclipse.org", topic)

	// Attempt a connection to the specified MQTT broker
	client.Connect()
	defer client.Disconnect()

	// Attempt to publish a message
	err := client.Publish("hello world")
	if err != nil {
		log.Printf("could not send message: %v\n", err)
	}
}
more

There are more examples in the examples folder, with proper error handling and some logging:

  • connect and disconnect to a broker
  • publishing a message a topic
  • subscribing to a topic
Go

If you have Go installed you can run them with go run ./examples/<example>.

CLI

If you don't have Go installed, the examples have been compiled to binaries for Linux (x86 and Arm) and Darwin (macOS). These can found in the releases page. Download the correct .tar.gz for your platform and once uncompressed, the binaries will be in an examples folder. These are CLIs and can be ran directly from your terminal.

Docker

Each example has a Dockerfile if you don't have Go installed (and have Docker installed). To build an image, run docker build -t <image-name> . from an example directory.

For example, from the examples/connect directory run docker build -t conngoqtt .. Then to use the container, run docker run conngoqtt.

Limitations

Currently, goqtt does not implement the full MQTT 3.1.1 client specification.

The two main omissions from the spec are packets with QoS > 0 and username/password message payloads in CONNECT packets. Because of these, goqtt should be used with care in any environment that requires sensitive or important data.

QoS

For detailed information please refer to the spec, but with QoS set at 0 each packet is sent at most once. To quote the spec:

The message is delivered according to the capabilities of the underlying network. No response is sent by the receiver and no retry is performed by the sender. The message arrives at the receiver either once or not at all.

If a packet is encountered by goqtt with a higher QoS it will likely crash.

Authentication/Security

Without any support for username and password information to be sent to a broker there is no way for a client to authenticate. Please carefully consider if this is an acceptable security risk for your use case.

The MQTT spec does not require the use of TLS/SSL, however there are brokers that support TLS. goqtt does not support TLS connections. Please carefully consider if this is an acceptable security risk for your use case.

Other

A more minor omission is the lack of support for multiple topic subscriptions or wildcard subscriptions. A topic must be fully formed, e.g. goqtt/hello.

Logging

WIP

goqtt uses zerolog internally for creating structured logs with different levels (such as DEBUG, INFO, and ERROR).

However, all log statements are disabled by default. If you'd like to enable the logging, set the global log level to the desired level. This is done with the zerolog.SetGlobalLevel() function and a parameter such as zerolog.InfoLevel. See the examples and their documentation for more levels.

Inspiration

The eclipse paho golang MQTT library has been a large inspiration and resource for this project. Much thanks to them.

Documentation

Overview

Package goqtt is a MQTT 3.1.1 client library.

It does not implement the full client specification, see README for more information.

Use an instantiated Client to interact with a MQTT broker:

client := goqtt.NewClient("example.broker")
err := client.Connect()
...
err := client.Subscribe()
...
err := client.Publish("hello world")
...
mes, err := client.ReadLoop() // call in a 'for' loop for indefinite reading
...

It is nice to let the broker know when you are disconnecting:

err := client.Connect()
if err != nil {
	// handle error
}
defer client.Disconnect()

To configure a Client, the only required parameter is the address of the broker. There are default values set for the other options. See the Constants section for their values.

client := goqtt.NewClient("example.broker")

The other configuration options are: Port, Topic, ClientId, and KeepAlive. To set these, use their functions and pass to the NewClient:

p := goqtt.Port("1883")
t := goqtt.Topic("hello/world")
cid := goqtt.ClientId("goqtt-clientId")
ka := goqtt.KeepAlive(15)  // seconds

client := goqtt.NewClient("example.broker", p, t, cid, ka)

Note that you can pass any of these options, you don't need to pass all of them.

Index

Examples

Constants

View Source
const (
	DefaultPort      = "1883"
	DefaultKeepAlive = 60 // seconds
	DefaultTopic     = "goqtt"
)

Default values for the Client configuration. See the DefaultClientId function for the Client's default ClientId value.

Variables

This section is empty.

Functions

func ClientId added in v0.0.10

func ClientId(cid string) option

ClientId is the identifier you use to tell the MQTT broker who you are. A broker will require unique ClientId's for all connected clients.

func DefaultClientId added in v0.0.10

func DefaultClientId() string

DefaultClientId creates a default value for the Client's clientId. It uses the process id and the current time to try to prevent client collisions with the broker.

func KeepAlive added in v0.0.10

func KeepAlive(seconds int) option

KeepAlive is the time in seconds that the broker should wait before disconnecting you if no packets are sent.

func Port added in v0.0.10

func Port(port string) option

Port is the port number of the server. Usually 1883 (insecure) or 8883 (TLS).

func Topic added in v0.0.10

func Topic(topic string) option

Topic is the fully qualified topic to subscribe or publish to. Only single topics and no wildcards are accepted at this time.

Types

type Client added in v0.0.8

type Client struct {
	Config *clientConfig
	// contains filtered or unexported fields
}

Client is the main interaction point for sending and receiving Packets. An instantiated Client needs to call the Connect() method before sending/receiving any packets.

func NewClient added in v0.0.8

func NewClient(addr string, opts ...option) *Client

NewClient creates a Client struct which can be used to interact with a MQTT broker. It sets default values for most of the configuration, so only a server address is required to instantiate it. Other configuration options are available and can be passed in as needed.

func (*Client) Connect added in v0.0.8

func (c *Client) Connect() error

Connect attempts to create a TCP connection to the broker specified in the client's ClientConfig. It sends a CONNECT packet and reads the CONNACK packet.

func (*Client) Disconnect added in v0.0.8

func (c *Client) Disconnect()

Disconnect sends a DISCONNECT packet.

func (*Client) Publish added in v0.0.10

func (c *Client) Publish(message string) error

Publish sends a given message to the topic specified by the Client.

Example

This example subscribes to a MQTT broker will print any incoming messages to std out.

package main

import (
	"log"

	"github.com/andschneider/goqtt"
)

func main() {
	// Create Client
	client := goqtt.NewClient("mqtt.eclipse.org")

	// Attempt a connection to the specified MQTT broker
	client.Connect()
	defer client.Disconnect()

	// Attempt to publish a message
	err := client.Publish("hello world")
	if err != nil {
		log.Printf("could not send message: %v\n", err)
	}
}

func (*Client) ReadLoop added in v0.0.8

func (c *Client) ReadLoop() (*packets.PublishPacket, error)

ReadLoop should be used after a successful subscription to a topic and reads any incoming messages. It returns a PublishPacket if one has been received for further processing.

Example

This example subscribes to a MQTT broker will print any incoming messages to std out, until the program exits.

package main

import (
	"log"

	"github.com/andschneider/goqtt"
)

func main() {
	// Create Client
	client := goqtt.NewClient("mqtt.eclipse.org")

	// Attempt a connection to the specified MQTT broker
	client.Connect()
	defer client.Disconnect()

	// Attempt to subscribe to the topic
	client.Subscribe()

	// Read messages indefinitely
	for {
		log.Println("waiting for message")
		m, _ := client.ReadLoop()
		if m != nil {
			log.Printf("received message: '%s' from topic: '%s'", string(m.Message), m.Topic)
		}
	}
}

func (*Client) SendPing added in v0.0.8

func (c *Client) SendPing() error

SendPing creates a Ping packet and writes it to the client's TCP connection right away.

func (*Client) Subscribe added in v0.0.8

func (c *Client) Subscribe() error

Subscribe attempts to create a subscription for a client to it's configured topic. It sends a SUBSCRIBE packet and reads the SUBACK packet.

Example

This example subscribes to a MQTT broker. You will want to call ReadLoop afterwards to process incoming messages.

package main

import (
	"log"

	"github.com/andschneider/goqtt"
)

func main() {
	// Create Client
	client := goqtt.NewClient("mqtt.eclipse.org")

	// Attempt a connection to the specified MQTT broker
	client.Connect()
	defer client.Disconnect()

	// Attempt to subscribe to the topic
	err := client.Subscribe()
	if err != nil {
		log.Fatalf("could not subscribe to topic: %v\n", err)
	}
}

func (*Client) Unsubscribe added in v0.0.8

func (c *Client) Unsubscribe() error

Unsubscribe sends an UNSUBSCRIBE packet for a given topic and reads the UNSUBACK packet.

Directories

Path Synopsis
examples
connect command
This example simply connects to a MQTT broker and then terminates.
This example simply connects to a MQTT broker and then terminates.
publish command
This example publishes a message to a given topic to run: go run ./examples/publish/main.go The default broker is the publicly available server hosted by the Eclipse foundation, but can be changed by specifying a different host name or IP address with the -server flag.
This example publishes a message to a given topic to run: go run ./examples/publish/main.go The default broker is the publicly available server hosted by the Eclipse foundation, but can be changed by specifying a different host name or IP address with the -server flag.
subscribe command
This example subscribes to a MQTT broker will print any incoming messages to the terminal.
This example subscribes to a MQTT broker will print any incoming messages to the terminal.
Package packets make up the MQTT control packets and their core functionality.
Package packets make up the MQTT control packets and their core functionality.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL