Skip to content

Commit

Permalink
Merge pull request #461 from ChIoT-Tech/master
Browse files Browse the repository at this point in the history
Update README and add docker example (mainly as a base for reproducing issues)
  • Loading branch information
Al S-M committed Oct 31, 2020
2 parents ba85050 + c4cc28c commit 43c9c44
Show file tree
Hide file tree
Showing 16 changed files with 636 additions and 16 deletions.
133 changes: 117 additions & 16 deletions README.md
Expand Up @@ -6,24 +6,39 @@ Eclipse Paho MQTT Go client
===========================


This repository contains the source code for the [Eclipse Paho](http://eclipse.org/paho) MQTT Go client library.
This repository contains the source code for the [Eclipse Paho](https://eclipse.org/paho) MQTT 3.1/3.11 Go client library.

This code builds a library which enable applications to connect to an [MQTT](http://mqtt.org) broker to publish messages, and to subscribe to topics and receive published messages.
This code builds a library which enable applications to connect to an [MQTT](https://mqtt.org) broker to publish
messages, and to subscribe to topics and receive published messages.

This library supports a fully asynchronous mode of operation.

A client supporting MQTT V5 is [also available](https://github.com/eclipse/paho.golang).

Installation and Build
----------------------

This client is designed to work with the standard Go tools, so installation is as easy as:
The process depends upon whether you are using [modules](https://golang.org/ref/mod) (recommended) or `GOPATH`.

#### Modules

If you are using [modules](https://blog.golang.org/using-go-modules) then `import "github.com/eclipse/paho.mqtt.golang"`
and start using it. The necessary packages will be download automatically when you run `go build`.

Note that the latest release will be downloaded and changes may have been made since the release. If you have
encountered an issue, or wish to try the latest code for another reason, then run
`go get github.com/eclipse/paho.mqtt.golang@master` to get the latest commit.

#### GOPATH

Installation is as easy as:

```
go get github.com/eclipse/paho.mqtt.golang
```

The client depends on Google's [proxy](https://godoc.org/golang.org/x/net/proxy) package and the [websockets](https://godoc.org/github.com/gorilla/websocket) package,
also easily installed with the commands:
The client depends on Google's [proxy](https://godoc.org/golang.org/x/net/proxy) package and the
[websockets](https://godoc.org/github.com/gorilla/websocket) package, also easily installed with the commands:

```
go get github.com/gorilla/websocket
Expand All @@ -35,31 +50,114 @@ Usage and API
-------------

Detailed API documentation is available by using to godoc tool, or can be browsed online
using the [godoc.org](http://godoc.org/github.com/eclipse/paho.mqtt.golang) service.

Make use of the library by importing it in your Go client source code. For example,
```
import "github.com/eclipse/paho.mqtt.golang"
```
using the [godoc.org](https://godoc.org/github.com/eclipse/paho.mqtt.golang) service.

Samples are available in the `cmd` directory for reference.

Note:

The library also supports using MQTT over websockets by using the `ws://` (unsecure) or `wss://` (secure) prefix in the URI. If the client is running behind a corporate http/https proxy then the following environment variables `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` are taken into account when establishing the connection.

The library also supports using MQTT over websockets by using the `ws://` (unsecure) or `wss://` (secure) prefix in the
URI. If the client is running behind a corporate http/https proxy then the following environment variables `HTTP_PROXY`,
`HTTPS_PROXY` and `NO_PROXY` are taken into account when establishing the connection.

Runtime tracing
Troubleshooting
---------------

Tracing is enabled by assigning logs (from the Go log package) to the logging endpoints, ERROR, CRITICAL, WARN and DEBUG
If you are new to MQTT and your application is not working as expected reviewing the
[MQTT specification](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html), which this library implements,
is a good first step. [MQTT.org](https://mqtt.org) has some [good resources](https://mqtt.org/getting-started/) that answer many
common questions.

### Error Handling

The asynchronous nature of this library makes it easy to forget to check for errors. Consider using a go routine to
log these:

```go
t := client.Publish("topic", qos, retained, msg)
go func() {
_ = t.Wait() // Can also use '<-t.Done()' in releases > 1.2.0
if t.Error() != nil {
log.Error(t.Error()) // Use your preferred logging technique (or just fmt.Printf)
}
}()
```

### Logging

If you are encountering issues then enabling logging, both within this library and on your broker, is a good way to
begin troubleshooting. This library can produce various levels of log by assigning the logging endpoints, ERROR,
CRITICAL, WARN and DEBUG. For example:

```go
func main() {
mqtt.ERROR = log.New(os.Stdout, "[ERROR] ", 0)
mqtt.CRITICAL = log.New(os.Stdout, "[CRIT] ", 0)
mqtt.WARN = log.New(os.Stdout, "[WARN] ", 0)
mqtt.DEBUG = log.New(os.Stdout, "[DEBUG] ", 0)

// Connect, Subscribe, Publish etc..
}
```

### Common Problems

* Seemingly random disconnections may be caused by another client connecting to the broker with the same client
identifier; this is as per the [spec](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc384800405).
* A `MessageHandler` (called when a new message is received) must not block. If you wish to perform a long-running task,
or publish a message, then please use a go routine (blocking in the handler is a common cause of unexpected `pingresp
not received, disconnecting` errors).
* When subscribing at QOS2 with `CleanSession` set to false it is possible that the broker will deliver retained
messages before `Subscribe` can be called. To process these messages either configure a handler with `AddRoute` or
set a `DefaultPublishHandler`.
* Loss of network connectivity may not be detected immediately. If this is an issue then consider setting
`ClientOptions.KeepAlive` (sends regular messages to check the link is active).
* Brokers offer many configuration options; some settings may lead to unexpected results. If using Mosquitto check
`max_inflight_messages`, `max_queued_messages`, `persistence` (the defaults may not be what you expect).

Reporting bugs
--------------

Please report bugs by raising issues for this project in github https://github.com/eclipse/paho.mqtt.golang/issues
Please report bugs by raising issues for this project in github https://github.com/eclipse/paho.mqtt.golang/issues

*A limited number of contributors monitor the issues section so if you have a general question please consider the
resources in the [more information](#more-information) section (your question will be seen by more people, and you are
likely to receive an answer more quickly).*

We welcome bug reports, but it is important they are actionable. A significant percentage of issues reported are not
resolved due to a lack of information. If we cannot replicate the problem then it is unlikely we will be able to fix it.
The information required will vary from issue to issue but consider including:

* A [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). Providing an example
is the best way to demonstrate the issue you are facing; it is important this includes all relevant information
(including broker configuration). Docker (see `cmd/docker`) makes it relatively simple to provide a working end-to-end
example.
* A full, clear, description of the problem (detail what you are expecting vs what actually happens).
* Details of your attempts to resolve the issue (what have you tried, what worked, what did not).
* [Application Logs](#logging) covering the period the issue occurred.
* Broker Logs covering the period the issue occurred.

It is important to remember that this library does not stand alone; it communicates with a broker and any issues you are
seeing may be due to:

* Bugs in your code.
* Bugs in this library.
* The broker configuration.
* Bugs in the broker.
* Issues with whatever you are communicating with.

When submitting an issue please ensure that you provide sufficient details to enable us to eliminate causes outside of
this library.

Contributing
------------

We welcome pull requests but before your contribution can be accepted by the project, you need to create and
electronically sign the Eclipse Contributor Agreement (ECA) and sign off on the Eclipse Foundation Certificate of Origin.

More information is available in the
[Eclipse Development Resources](http://wiki.eclipse.org/Development_Resources/Contributing_via_Git); please take special
note of the requirement that the commit record contain a "Signed-off-by" entry.

More information
----------------
Expand All @@ -69,3 +167,6 @@ Discussion of the Paho clients takes place on the [Eclipse paho-dev mailing list
General questions about the MQTT protocol are discussed in the [MQTT Google Group](https://groups.google.com/forum/?hl=en-US&fromgroups#!forum/mqtt).

There is much more information available via the [MQTT community site](http://mqtt.org).

[Stack Overflow](https://stackoverflow.com/questions/tagged/mqtt+go) has a range questions covering a range of common
issues (both relating to use of this library and MQTT in general).
44 changes: 44 additions & 0 deletions cmd/docker/binds/mosquitto/config/mosquitto.conf
@@ -0,0 +1,44 @@
# Config file for mosquitto
#
# See mosquitto.conf(5) for more information.
#
# This is a very basic configuration (no security etc - do not use in production!)
# If you are using this to replicate a bug please copy your own configuration in here (changing folders as necessary)

allow_anonymous true # Anyone can connect

# Port to use for the default listener.
#port 1883

#log_type error
#log_type warning
#log_type notice
#log_type information
log_type all

# Log to the console (visible using `docker-compose logs`). To log to a file uncomment the line below
log_dest stdout
#log_dest file /mosquitto/log/mosquitto.log

# Log entries are easier to read with an ISO 8601 timestamp
log_timestamp true
log_timestamp_format %Y-%m-%dT%H:%M:%S

# For demonstration purposes we will not store messages to disk (the appropriate value depends upon what you are testing)
# Note: If enabled then you will probably want to add a bind to the docker-compose.yml so the persistence_file is retained.
#persistence false

#persistence true
#autosave_interval 20
#persistence_location /mosquitto/data/
#persistence_file mosquitto.db

# The maximum number of QoS 1 and 2 messages to hold in a queue per client
# above those that are currently in-flight. Defaults to 100. Set
# to 0 for no maximum (not recommended).
# We do set this to 0 for testing because the default is may result in lost messages if there are a lot of
# messages waiting when the connection is re-established (they will all be sent immediately). This should not be
# 0 on a production system (but the value chosen should take into account likely queue sizes and bandwidth)
max_queued_messages 0


4 changes: 4 additions & 0 deletions cmd/docker/binds/mosquitto/data/readme.md
@@ -0,0 +1,4 @@
data
====

If you enable persistence in `mosquitto.conf` then the database will be written here.
4 changes: 4 additions & 0 deletions cmd/docker/binds/mosquitto/log/readme.md
@@ -0,0 +1,4 @@
log
===

If you enable logging to a file in the `mosquitto.conf` then the logs will be written here
7 changes: 7 additions & 0 deletions cmd/docker/binds/readme.md
@@ -0,0 +1,7 @@
Binds
=====

Folders within this folder will be bound to folders within the containers; this includes the mosquitto
configuration and persistence files.

Note: While testing some files within these folders may become large and should be deleted when appropriate.
4 changes: 4 additions & 0 deletions cmd/docker/binds/sub/readme.md
@@ -0,0 +1,4 @@
sub
===

If you configure the `sub` application to write to disk then the output will go here.
42 changes: 42 additions & 0 deletions cmd/docker/docker-compose.yml
@@ -0,0 +1,42 @@
version: "3.8"
services:
mosquitto:
image: eclipse-mosquitto
networks:
- test-net
ports:
- target: 8883
published: 8883
protocol: tcp
mode: host
volumes:
- type: bind
source: ./binds/mosquitto/config
target: /mosquitto/config
read_only: true
- type: bind
source: ./binds/mosquitto/data
target: /mosquitto/data
- type: bind
source: ./binds/mosquitto/log
target: /mosquitto/log
pub:
build: publisher/.
networks:
- test-net
depends_on:
- mosquitto
sub:
build: subscriber/.
networks:
- test-net
depends_on:
- mosquitto
volumes:
- type: bind
source: ./binds/sub
target: /binds
read_only: false
networks:
test-net:
external: false
15 changes: 15 additions & 0 deletions cmd/docker/publisher/dockerfile
@@ -0,0 +1,15 @@
# Compile stage
FROM golang:alpine AS build-env
ENV CGO_ENABLED 0

ADD . /pub_src
WORKDIR /pub_src
RUN go build -gcflags "all=-N -l" -o /pub

# Final stage
FROM alpine:latest

COPY --from=build-env /pub /

# Run
CMD ["/pub"]
8 changes: 8 additions & 0 deletions cmd/docker/publisher/go.mod
@@ -0,0 +1,8 @@
module publisher

go 1.15

require (
github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200918111050-ba85050a1f23
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c // indirect
)
17 changes: 17 additions & 0 deletions cmd/docker/publisher/go.sum
@@ -0,0 +1,17 @@
github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200918111050-ba85050a1f23 h1:znRijtV5P9m5mmDsy4oesCPlCIPDILTj4wosaZWsTpY=
github.com/eclipse/paho.mqtt.golang v1.2.1-0.20200918111050-ba85050a1f23/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c h1:rpcgRPA7OvNEOdprt2Wx8/Re2cBTd8NPo/lvo3AyMqk=
golang.org/x/net v0.0.0-20201029055024-942e2f445f3c/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

0 comments on commit 43c9c44

Please sign in to comment.