From 444fa0b2e512d57544ca6eb002db696f0139d240 Mon Sep 17 00:00:00 2001 From: Steve Kamerman Date: Tue, 9 Apr 2019 15:41:01 -0400 Subject: [PATCH 1/3] Added WithCleanSession() option to allow persistent connections. --- v2/options.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/v2/options.go b/v2/options.go index 56254df..3ec2f99 100644 --- a/v2/options.go +++ b/v2/options.go @@ -105,6 +105,16 @@ func WithAutoReconnect(a bool) func(*Client) { } } +// WithCleanSession sets whether the MQTT session should be cleaned when the connection is lost. +// If false, the client will make a persistent connection and the server will attempt to store +// messages for the client upon unclean disconnection. If true, the client will need to resubscribe +// to all channels in the OnConnect() handler so subscriptions are not lost due to disconnect. Default: true. +func WithCleanSession(a bool) func(*Client) { + return func(c *Client) { + c.opts.SetCleanSession(a) + } +} + // option represents a key/value pair that can be supplied to the publish/subscribe or unsubscribe // methods and provide ways to configure the operation. type option string From 8f3ee565ecb3e376000eca6ac62490234802eb62 Mon Sep 17 00:00:00 2001 From: Steve Kamerman Date: Mon, 29 Apr 2019 12:06:59 -0400 Subject: [PATCH 2/3] Added persistent channel subscription documentation --- README.md | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 378be85..bd2c742 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Emitter Golang SDK [![api documentation](http://b.repl.ca/v1/api-documentation-green.png)](https://godoc.org/github.com/emitter-io/go) This repository contains Go/Golang client for [Emitter](https://emitter.io) (see also on [Emitter GitHub](https://github.com/emitter-io/emitter)). Emitter is an **open-source** real-time communication service for connecting online devices. At its core, emitter.io is a distributed, scalable and fault-tolerant publish-subscribe messaging platform based on MQTT protocol and featuring message storage. -This library provides a nicer MQTT interface fine-tuned and extended with specific features provided by [Emitter](https://emitter.io). The code uses the [Eclipse Paho MQTT Go Client](https://github.com/eclipse/paho.mqtt.golang) for handling all the network communication and MQTT protocol, and is released under the same license (EPL v1). +This library provides a nicer MQTT interface fine-tuned and extended with specific features provided by [Emitter](https://emitter.io). The code uses the [Eclipse Paho MQTT Go Client](https://github.com/eclipse/paho.mqtt.golang) for handling all the network communication and MQTT protocol, and is released under the same license (EPL v1). ## Usage -This library aims to be as simple and straighforward as possible. First thing you'll need to do is to import it. +This library aims to be as simple and straightforward as possible. First thing you'll need to do is to import it. ```go import emitter "github.com/emitter-io/go/v2" @@ -13,6 +13,7 @@ import emitter "github.com/emitter-io/go/v2" Then, you can use the functions exposed by `Emitter` type - they are simple methods such as `Connect`, `Publish`, `Subscribe`, `Unsubscribe`, `GenerateKey`, `Presence`, etc. See the example below. +### General Example ```go func main() { @@ -58,6 +59,39 @@ func main() { } ``` +### Maintaining a Channel Subscription +By default, the client will *reconnect but not resubscribe to your previously-subscribed channels* if a network interruption or other disconnection occurs. This is the intended behavior and is aligned with the other Emitter and generic MQTT clients. There are two ways to maintain your channel subscriptions across reconnections: + +#### Method 1: Subscribe in the OnConnect() handler: +```go +// Subscribe to the channels in OnConnect() so they are re-subscribed on reconnect +c.OnConnect(func(c *emitter.Client) { + c.Subscribe(key, channel, nil) +}) + +// Create the client and connect to the broker +c, _ := emitter.Connect("", func(_ *emitter.Client, msg emitter.Message) { + fmt.Printf("Received: '%s' topic: '%s'\n", msg.Payload(), msg.Topic()) +}) +``` + +#### Method 2: Use Persistent Connections: +The MQTT protocol has a flag called `cleanSession` that allows a client to maintain a persistent connection to the broker. Upon disconnection, the broker will continue to store information about the client session (such as the list of active subscriptions) and will continue queuing messages for the client. When the client reconnects (with the same ID/username [see `emitter.Client.WithUsername()`]), it will receive the missed messages, assuming there were enough resources on the broker to store them all. The persistent connection information is stored on the broker until the client sends another connection request with `cleanSession=true`. It is important to understand the ramifications of using this option, so you should [checkout the documentation](https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/tt60370_.htm) for more details. + +```go +c = emitter.NewClient( + // Make a persistent connection by setting cleanSession=false + emitter.WithCleanSession(false), +) + +// Connect to the broker +emitter.Connect("", func(_ *emitter.Client, msg emitter.Message) { + fmt.Printf("Received: '%s' topic: '%s'\n", msg.Payload(), msg.Topic()) +}) + +c.Subscribe(key, channel, nil) +``` + ## Installation and Build This client, similarly to the Eclipse Paho client is designed to work with the standard Go tools, so installation is as easy as: From 978f98586cca45bc8cfcaf161a0e397a5be138c4 Mon Sep 17 00:00:00 2001 From: Steve Kamerman Date: Mon, 29 Apr 2019 12:36:52 -0400 Subject: [PATCH 3/3] Added a note about resubscribes near the first example --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bd2c742..457150a 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ import emitter "github.com/emitter-io/go/v2" Then, you can use the functions exposed by `Emitter` type - they are simple methods such as `Connect`, `Publish`, `Subscribe`, `Unsubscribe`, `GenerateKey`, `Presence`, etc. See the example below. +> Note: If there is a network interruption or some other disconnection, the client will automatically reconnect, but *it will not automatically resubscribe to your channels*. See the [Maintaining a Channel Subscription](#maintaining-a-channel-subscription) section below! + ### General Example ```go func main() {