Skip to content

Commit ef555c5

Browse files
author
Al S-M
committed
Bring packet library internal an fix golint reported issues
The packet handling library is now internal to the Paho client rather than an external dependency. Additionally I have resolved a lot of the issues reported by golint.
1 parent 433fbc4 commit ef555c5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1838
-626
lines changed

client.go

+70-70
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ package mqtt
1717

1818
import (
1919
"errors"
20-
. "github.com/alsm/hrotti/packets"
20+
"git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git/packets"
2121
"net"
2222
"sync"
2323
"time"
2424
)
2525

26-
type Client interface {
26+
// ClientInt is the interface definition for a Client as used by this
27+
// library, the interface is primarily to allow mocking tests.
28+
type ClientInt interface {
2729
IsConnected() bool
2830
Connect() Token
2931
Disconnect(uint)
@@ -35,34 +37,31 @@ type Client interface {
3537
Unsubscribe(...string) Token
3638
}
3739

38-
// MqttClient is a lightweight MQTT v3.1 Client for communicating
40+
// Client is an MQTT v3.1.1 client for communicating
3941
// with an MQTT server using non-blocking methods that allow work
4042
// to be done in the background.
41-
4243
// An application may connect to an MQTT server using:
4344
// A plain TCP socket
4445
// A secure SSL/TLS socket
4546
// A websocket
46-
4747
// To enable ensured message delivery at Quality of Service (QoS) levels
4848
// described in the MQTT spec, a message persistence mechanism must be
4949
// used. This is done by providing a type which implements the Store
5050
// interface. For convenience, FileStore and MemoryStore are provided
5151
// implementations that should be sufficient for most use cases. More
5252
// information can be found in their respective documentation.
53-
5453
// Numerous connection options may be specified by configuring a
5554
// and then supplying a ClientOptions type.
56-
type MqttClient struct {
55+
type Client struct {
5756
sync.RWMutex
5857
messageIds
5958
conn net.Conn
60-
ibound chan ControlPacket
59+
ibound chan packets.ControlPacket
6160
obound chan *PacketAndToken
6261
oboundP chan *PacketAndToken
6362
msgRouter *router
6463
stopRouter chan bool
65-
incomingPubChan chan *PublishPacket
64+
incomingPubChan chan *packets.PublishPacket
6665
errors chan error
6766
stop chan struct{}
6867
persist Store
@@ -77,8 +76,8 @@ type MqttClient struct {
7776
// in the provided ClientOptions. The client must have the Start method called
7877
// on it before it may be used. This is to make sure resources (such as a net
7978
// connection) are created before the application is actually ready.
80-
func NewClient(o *ClientOptions) *MqttClient {
81-
c := &MqttClient{}
79+
func NewClient(o *ClientOptions) *Client {
80+
c := &Client{}
8281
c.options = *o
8382

8483
if c.options.Store == nil {
@@ -99,31 +98,39 @@ func NewClient(o *ClientOptions) *MqttClient {
9998
return c
10099
}
101100

102-
func (c *MqttClient) IsConnected() bool {
101+
// IsConnected returns a bool signifying whether
102+
// the client is connected or not.
103+
func (c *Client) IsConnected() bool {
103104
c.RLock()
104105
defer c.RUnlock()
105106
return c.connected
106107
}
107108

109+
func (c *Client) setConnected(status bool) {
110+
c.Lock()
111+
defer c.Unlock()
112+
c.connected = status
113+
}
114+
108115
// Connect will create a connection to the message broker
109116
// If clean session is false, then a slice will
110117
// be returned containing Receipts for all messages
111118
// that were in-flight at the last disconnect.
112119
// If clean session is true, then any existing client
113120
// state will be removed.
114-
func (c *MqttClient) Connect() Token {
121+
func (c *Client) Connect() Token {
115122
var err error
116-
t := newToken(CONNECT).(*ConnectToken)
123+
t := newToken(packets.Connect).(*ConnectToken)
117124
DEBUG.Println(CLI, "Connect()")
118125

119126
go func() {
120127
var rc byte
121-
cm := newConnectMsgFromOptions(c.options)
128+
cm := newConnectMsgFromOptions(&c.options)
122129

123130
for _, broker := range c.options.Servers {
124131
CONN:
125132
DEBUG.Println(CLI, "about to write new connect msg")
126-
c.conn, err = openConnection(broker, &c.options.TlsConfig)
133+
c.conn, err = openConnection(broker, &c.options.TLSConfig)
127134
if err == nil {
128135
DEBUG.Println(CLI, "socket connected to broker")
129136
switch c.options.ProtocolVersion {
@@ -140,12 +147,12 @@ func (c *MqttClient) Connect() Token {
140147
cm.Write(c.conn)
141148

142149
rc = c.connect()
143-
if rc != CONN_ACCEPTED {
150+
if rc != packets.Accepted {
144151
c.conn.Close()
145152
c.conn = nil
146153
//if the protocol version was explicitly set don't do any fallback
147154
if c.options.protocolVersionExplicit {
148-
ERROR.Println(CLI, "Connecting to", broker, "CONNACK was not CONN_ACCEPTED, but rather", ConnackReturnCodes[rc])
155+
ERROR.Println(CLI, "Connecting to", broker, "CONNACK was not CONN_ACCEPTED, but rather", packets.ConnackReturnCodes[rc])
149156
continue
150157
}
151158
if c.options.ProtocolVersion == 4 {
@@ -158,14 +165,14 @@ func (c *MqttClient) Connect() Token {
158165
} else {
159166
ERROR.Println(CLI, err.Error())
160167
WARN.Println(CLI, "failed to connect to broker, trying next")
161-
rc = CONN_NETWORK_ERROR
168+
rc = packets.NetworkError
162169
}
163170
}
164171

165172
if c.conn == nil {
166173
ERROR.Println(CLI, "Failed to connect to a broker")
167174
t.returnCode = rc
168-
if rc != CONN_NETWORK_ERROR {
175+
if rc != packets.NetworkError {
169176
t.err = connErrors[rc]
170177
} else {
171178
t.err = errors.New(connErrors[rc].Error() + " : " + err.Error())
@@ -179,11 +186,11 @@ func (c *MqttClient) Connect() Token {
179186

180187
c.obound = make(chan *PacketAndToken, 100)
181188
c.oboundP = make(chan *PacketAndToken, 100)
182-
c.ibound = make(chan ControlPacket)
189+
c.ibound = make(chan packets.ControlPacket)
183190
c.errors = make(chan error)
184191
c.stop = make(chan struct{})
185192

186-
c.incomingPubChan = make(chan *PublishPacket, 100)
193+
c.incomingPubChan = make(chan *packets.PublishPacket, 100)
187194
c.msgRouter.matchAndDispatch(c.incomingPubChan, c.options.Order, c)
188195

189196
c.workers.Add(1)
@@ -213,26 +220,26 @@ func (c *MqttClient) Connect() Token {
213220
c.workers.Add(1)
214221
go incoming(c)
215222

216-
DEBUG.Println(CLI, "exit startMqttClient")
223+
DEBUG.Println(CLI, "exit startClient")
217224
t.flowComplete()
218225
}()
219226
return t
220227
}
221228

222229
// internal function used to reconnect the client when it loses its connection
223-
func (c *MqttClient) reconnect() {
230+
func (c *Client) reconnect() {
224231
DEBUG.Println(CLI, "enter reconnect")
225232
var rc byte = 1
226233
var sleep uint = 1
227234
var err error
228235

229236
for rc != 0 {
230-
cm := newConnectMsgFromOptions(c.options)
237+
cm := newConnectMsgFromOptions(&c.options)
231238

232239
for _, broker := range c.options.Servers {
233240
CONN:
234241
DEBUG.Println(CLI, "about to write new connect msg")
235-
c.conn, err = openConnection(broker, &c.options.TlsConfig)
242+
c.conn, err = openConnection(broker, &c.options.TLSConfig)
236243
if err == nil {
237244
DEBUG.Println(CLI, "socket connected to broker")
238245
switch c.options.ProtocolVersion {
@@ -249,12 +256,12 @@ func (c *MqttClient) reconnect() {
249256
cm.Write(c.conn)
250257

251258
rc = c.connect()
252-
if rc != CONN_ACCEPTED {
259+
if rc != packets.Accepted {
253260
c.conn.Close()
254261
c.conn = nil
255262
//if the protocol version was explicitly set don't do any fallback
256263
if c.options.protocolVersionExplicit {
257-
ERROR.Println(CLI, "Connecting to", broker, "CONNACK was not CONN_ACCEPTED, but rather", ConnackReturnCodes[rc])
264+
ERROR.Println(CLI, "Connecting to", broker, "CONNACK was not Accepted, but rather", packets.ConnackReturnCodes[rc])
258265
continue
259266
}
260267
if c.options.ProtocolVersion == 4 {
@@ -267,7 +274,7 @@ func (c *MqttClient) reconnect() {
267274
} else {
268275
ERROR.Println(CLI, err.Error())
269276
WARN.Println(CLI, "failed to connect to broker, trying next")
270-
rc = CONN_NETWORK_ERROR
277+
rc = packets.NetworkError
271278
}
272279
}
273280
if rc != 0 {
@@ -286,7 +293,7 @@ func (c *MqttClient) reconnect() {
286293
go outgoing(c)
287294
go alllogic(c)
288295

289-
c.connected = true
296+
c.setConnected(true)
290297
DEBUG.Println(CLI, "client is reconnected")
291298
if c.options.OnConnect != nil {
292299
go c.options.OnConnect(c)
@@ -304,18 +311,18 @@ func (c *MqttClient) reconnect() {
304311
// when the connection is first started.
305312
// This prevents receiving incoming data while resume
306313
// is in progress if clean session is false.
307-
func (c *MqttClient) connect() byte {
314+
func (c *Client) connect() byte {
308315
DEBUG.Println(NET, "connect started")
309316

310-
ca, err := ReadPacket(c.conn)
317+
ca, err := packets.ReadPacket(c.conn)
311318
if err != nil {
312319
ERROR.Println(NET, "connect got error", err)
313320
//c.errors <- err
314-
return CONN_NETWORK_ERROR
321+
return packets.NetworkError
315322
}
316-
msg := ca.(*ConnackPacket)
323+
msg := ca.(*packets.ConnackPacket)
317324

318-
if msg == nil || msg.FixedHeader.MessageType != CONNACK {
325+
if msg == nil || msg.FixedHeader.MessageType != packets.Connack {
319326
ERROR.Println(NET, "received msg that was nil or not CONNACK")
320327
} else {
321328
DEBUG.Println(NET, "received connack")
@@ -326,46 +333,39 @@ func (c *MqttClient) connect() byte {
326333
// Disconnect will end the connection with the server, but not before waiting
327334
// the specified number of milliseconds to wait for existing work to be
328335
// completed.
329-
func (c *MqttClient) Disconnect(quiesce uint) {
336+
func (c *Client) Disconnect(quiesce uint) {
330337
if !c.IsConnected() {
331338
WARN.Println(CLI, "already disconnected")
332339
return
333340
}
334341
DEBUG.Println(CLI, "disconnecting")
335-
c.connected = false
342+
c.setConnected(false)
343+
344+
dm := packets.NewControlPacket(packets.Disconnect).(*packets.DisconnectPacket)
345+
dt := newToken(packets.Disconnect)
346+
c.oboundP <- &PacketAndToken{p: dm, t: dt}
336347

337348
// wait for work to finish, or quiesce time consumed
338-
end := time.After(time.Duration(quiesce) * time.Millisecond)
339-
340-
// for now we just wait for the time specified and hope the work is done
341-
select {
342-
case <-end:
343-
DEBUG.Println(CLI, "quiesce expired, forcing disconnect")
344-
// case <- other:
345-
// DEBUG.Println(CLI, "finished processing work, graceful disconnect")
346-
}
349+
dt.WaitTimeout(time.Duration(quiesce) * time.Millisecond)
347350
c.disconnect()
348351
}
349352

350353
// ForceDisconnect will end the connection with the mqtt broker immediately.
351-
func (c *MqttClient) ForceDisconnect() {
354+
func (c *Client) ForceDisconnect() {
352355
if !c.IsConnected() {
353356
WARN.Println(CLI, "already disconnected")
354357
return
355358
}
359+
c.setConnected(false)
360+
c.conn.Close()
356361
DEBUG.Println(CLI, "forcefully disconnecting")
357362
c.disconnect()
358363
}
359364

360-
func (c *MqttClient) disconnect() {
361-
c.connected = false
362-
dm := NewControlPacket(DISCONNECT).(*DisconnectPacket)
363-
364-
// Send disconnect message and stop outgoing
365-
c.oboundP <- &PacketAndToken{p: dm, t: nil}
366-
// Stop all go routines
365+
func (c *Client) disconnect() {
367366
close(c.stop)
368-
367+
//Wait for all workers to finish before closing connection
368+
c.workers.Wait()
369369
DEBUG.Println(CLI, "disconnected")
370370
c.persist.Close()
371371
}
@@ -374,9 +374,9 @@ func (c *MqttClient) disconnect() {
374374
// and content to the specified topic.
375375
// Returns a read only channel used to track
376376
// the delivery of the message.
377-
func (c *MqttClient) Publish(topic string, qos byte, retained bool, payload interface{}) Token {
378-
token := newToken(PUBLISH).(*PublishToken)
379-
pub := NewControlPacket(PUBLISH).(*PublishPacket)
377+
func (c *Client) Publish(topic string, qos byte, retained bool, payload interface{}) Token {
378+
token := newToken(packets.Publish).(*PublishToken)
379+
pub := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
380380
pub.Qos = qos
381381
pub.TopicName = topic
382382
pub.Retain = retained
@@ -396,16 +396,16 @@ func (c *MqttClient) Publish(topic string, qos byte, retained bool, payload inte
396396
return token
397397
}
398398

399-
// Start a new subscription. Provide a MessageHandler to be executed when
399+
// Subscribe starts a new subscription. Provide a MessageHandler to be executed when
400400
// a message is published on the topic provided.
401-
func (c *MqttClient) Subscribe(topic string, qos byte, callback MessageHandler) Token {
402-
token := newToken(SUBSCRIBE).(*SubscribeToken)
401+
func (c *Client) Subscribe(topic string, qos byte, callback MessageHandler) Token {
402+
token := newToken(packets.Subscribe).(*SubscribeToken)
403403
DEBUG.Println(CLI, "enter Subscribe")
404404
if !c.IsConnected() {
405405
token.err = ErrNotConnected
406406
return token
407407
}
408-
sub := NewControlPacket(SUBSCRIBE).(*SubscribePacket)
408+
sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket)
409409
if err := validateTopicAndQos(topic, qos); err != nil {
410410
token.err = err
411411
return token
@@ -424,24 +424,24 @@ func (c *MqttClient) Subscribe(topic string, qos byte, callback MessageHandler)
424424
return token
425425
}
426426

427-
// Start a new subscription for multiple topics. Provide a MessageHandler to
427+
// SubscribeMultiple starts a new subscription for multiple topics. Provide a MessageHandler to
428428
// be executed when a message is published on one of the topics provided.
429-
func (c *MqttClient) SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token {
429+
func (c *Client) SubscribeMultiple(filters map[string]byte, callback MessageHandler) Token {
430430
var err error
431-
token := newToken(SUBSCRIBE).(*SubscribeToken)
431+
token := newToken(packets.Subscribe).(*SubscribeToken)
432432
DEBUG.Println(CLI, "enter SubscribeMultiple")
433433
if !c.IsConnected() {
434434
token.err = ErrNotConnected
435435
return token
436436
}
437-
sub := NewControlPacket(SUBSCRIBE).(*SubscribePacket)
437+
sub := packets.NewControlPacket(packets.Subscribe).(*packets.SubscribePacket)
438438
if sub.Topics, sub.Qoss, err = validateSubscribeMap(filters); err != nil {
439439
token.err = err
440440
return token
441441
}
442442

443443
if callback != nil {
444-
for topic, _ := range filters {
444+
for topic := range filters {
445445
c.msgRouter.addRoute(topic, callback)
446446
}
447447
}
@@ -455,14 +455,14 @@ func (c *MqttClient) SubscribeMultiple(filters map[string]byte, callback Message
455455
// Unsubscribe will end the subscription from each of the topics provided.
456456
// Messages published to those topics from other clients will no longer be
457457
// received.
458-
func (c *MqttClient) Unsubscribe(topics ...string) Token {
459-
token := newToken(UNSUBSCRIBE).(*UnsubscribeToken)
458+
func (c *Client) Unsubscribe(topics ...string) Token {
459+
token := newToken(packets.Unsubscribe).(*UnsubscribeToken)
460460
DEBUG.Println(CLI, "enter Unsubscribe")
461461
if !c.IsConnected() {
462462
token.err = ErrNotConnected
463463
return token
464464
}
465-
unsub := NewControlPacket(UNSUBSCRIBE).(*UnsubscribePacket)
465+
unsub := packets.NewControlPacket(packets.Unsubscribe).(*packets.UnsubscribePacket)
466466
unsub.Topics = make([]string, len(topics))
467467
copy(unsub.Topics, topics)
468468

components.go

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package mqtt
1616

1717
type component string
1818

19+
// Component names for debug output
1920
const (
2021
NET component = "[net] "
2122
PNG component = "[pinger] "

0 commit comments

Comments
 (0)