func NewUniqueIdentifier() string {
	return uuid.NewV4().String()
}
NewUniqueIdentifier returns a unique identifier that the client can use.
This identifier is what should be set for the lastWillID for anything
that is bridging more than one device
package flagmqtt
import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	mq "github.com/eclipse/paho.mqtt.golang"
	"github.com/satori/go.uuid"
	"io/ioutil"
	"os"
	"strings"
	"time"
)
type ClientConfig struct {
	WillTopic               string
	WillPayload             string
	WillQoS                 int
	WillRetain              bool
	ClientID                string
	OnConnectHandler        func(mq.Client)
	OnConnectionLostHandler func(mq.Client, error)
}
func NewPersistentMqtt(config ClientConfig) (mqttClient mq.Client, err error) {
	useTls := false
	if val, ok := os.LookupEnv("MQTT_TLS"); ok {
		useTls = val != "0" && val != "" && strings.ToLower(val) != "false"
	}
	if *MqttTLSFlag {
		useTls = true
	}
	caPath := envOrFlagStr(*MqttCAFlag, "MQTT_CA_PATH", "")
	certPath := envOrFlagStr(*MqttCertFlag, "MQTT_CERT_PATH", "")
	keyPath := envOrFlagStr(*MqttKeyFlag, "MQTT_KEY_PATH", "")
	address := envOrFlagStr(*MqttAddressFlag, "MQTT_ADDRESS", "localhost:1883")
	username := envOrFlagStr(*MqttUsernameFlag, "MQTT_USERNAME", "")
	password := envOrFlagStr(*MqttPasswordFlag, "MQTT_PASSWORD", "")
	connectionTimeout := envOrFlagInt(*MqttConnectionTimeout, "MQTT_CONNECTION_TIMEOUT", 10)
	keepAlive := envOrFlagInt(*MqttKeepAlive, "MQTT_KEEPALIVE", 5)
	maxReconnectInterval := envOrFlagInt(*MqttMaxReconnectInterval, "MQTT_MAX_RECONNECT_INTERVAL", 2)
	pingTimeout := envOrFlagInt(*MqttPingTimeout, "MQTT_PING_TIMEOUT", 10)
	writeTimeout := envOrFlagInt(*MqttWriteTimeout, "MQTT_WRITE_TIMEOUT", 5)
	var tlsCfg *tls.Config
	if useTls {
		tlsCfg, err = setupTLS(caPath, certPath, keyPath)
		if err != nil {
			return nil, err
		}
	}
	clientId := config.ClientID
	if clientId == "" {
		clientId = NewUniqueIdentifier()
	}
	opts := mq.NewClientOptions().
		SetClientID(clientId).
		SetConnectTimeout(time.Duration(connectionTimeout) * time.Second).
		SetKeepAlive(time.Duration(keepAlive) * time.Second).
		SetMaxReconnectInterval(time.Duration(maxReconnectInterval) * time.Minute).
		SetMessageChannelDepth(100).
		SetPingTimeout(time.Duration(pingTimeout) * time.Second).
		SetProtocolVersion(4).
		SetOrderMatters(false).
		SetWriteTimeout(time.Duration(writeTimeout) * time.Second)
	if config.OnConnectHandler != nil {
		opts.SetOnConnectHandler(config.OnConnectHandler)
	}
	if config.OnConnectionLostHandler != nil {
		opts.SetConnectionLostHandler(config.OnConnectionLostHandler)
	}
	if config.WillTopic != "" {
		opts.SetWill(
			config.WillTopic,
			config.WillPayload,
			byte(config.WillQoS&0xff),
			config.WillRetain,
		)
	}
	if username != "" {
		opts.SetUsername(username)
	}
	if password != "" {
		opts.SetPassword(password)
	}
	if useTls {
		opts.SetTLSConfig(tlsCfg)
		opts.AddBroker(fmt.Sprintf("ssl://%s", address))
	} else {
		opts.AddBroker(fmt.Sprintf("tcp://%s", address))
	}
	return mq.NewClient(opts), nil
}