@@ -36,6 +36,8 @@ type Client interface {
36
36
// the client wait group is done.
37
37
// The context used grpc stream to signal context done.
38
38
DisconnectContext (ctx context.Context ) error
39
+ // TopicFilter is used to receive filtered messages on specififc topic.
40
+ TopicFilter (subTopic string ) (* TopicFilter , error )
39
41
// Publish will publish a message with the specified DeliveryMode and content
40
42
// to the specified topic.
41
43
Publish (topic string , payload []byte , pubOpts ... PubOptions ) Result
@@ -54,6 +56,7 @@ type Client interface {
54
56
// received.
55
57
Unsubscribe (topics ... string ) Result
56
58
}
59
+
57
60
type client struct {
58
61
opts * options
59
62
context context.Context // context for the client
@@ -66,7 +69,7 @@ type client struct {
66
69
send chan * MessageAndResult
67
70
recv chan lp.MessagePack
68
71
pub chan * utp.Publish
69
- callbacks map [ uint64 ] MessageHandler
72
+ notifier * notifier
70
73
71
74
// Time when the keepalive session was last refreshed.
72
75
lastTouched atomic.Value
@@ -88,11 +91,11 @@ func NewClient(target, clientID string, opts ...Options) (Client, error) {
88
91
opts : new (options ),
89
92
context : ctx ,
90
93
cancel : cancel ,
91
- messageIds : messageIds {index : make (map [MID ]Result )},
94
+ messageIds : messageIds {index : make (map [MID ]Result ), resumedIds : make ( map [ MID ] struct {}) },
92
95
send : make (chan * MessageAndResult , 1 ), // buffered
93
96
recv : make (chan lp.MessagePack ),
94
97
pub : make (chan * utp.Publish ),
95
- callbacks : make ( map [ uint64 ] MessageHandler ),
98
+ notifier : newNotifier ( 100 ), // Notifier with Queue size 100
96
99
// close
97
100
closeC : make (chan struct {}),
98
101
}
@@ -103,7 +106,6 @@ func NewClient(target, clientID string, opts ...Options) (Client, error) {
103
106
// set default options
104
107
c .opts .addServer (target )
105
108
c .opts .setClientID (clientID )
106
- c .callbacks [0 ] = c .opts .defaultMessageHandler
107
109
108
110
// Open database connection
109
111
path := c .opts .storePath
@@ -150,6 +152,7 @@ func (c *client) close() error {
150
152
// close(c.ack)
151
153
close (c .recv )
152
154
close (c .pub )
155
+ c .notifier .close ()
153
156
store .Close ()
154
157
if c .cancel != nil {
155
158
c .cancel ()
@@ -315,6 +318,21 @@ func (c *client) serverDisconnect(err error) {
315
318
}
316
319
}
317
320
321
+ func (c * client ) TopicFilter (subscriptionTopic string ) (* TopicFilter , error ) {
322
+ topic := new (topic )
323
+ topic .parse (subscriptionTopic )
324
+ if err := topic .validate (validateMinLength ,
325
+ validateMaxLenth ,
326
+ validateMaxDepth ,
327
+ validateTopicParts ); err != nil {
328
+ return nil , err
329
+ }
330
+ t := & TopicFilter {subscriptionTopic : topic , updates : make (chan []PubMessage )}
331
+ c .notifier .addFilter (t .filter )
332
+
333
+ return t , nil
334
+ }
335
+
318
336
// Publish will publish a message with the specified DeliveryMode and content
319
337
// to the specified topic.
320
338
func (c * client ) Publish (pubTopic string , payload []byte , pubOpts ... PubOptions ) Result {
@@ -340,6 +358,13 @@ func (c *client) Publish(pubTopic string, payload []byte, pubOpts ...PubOptions)
340
358
return r
341
359
}
342
360
361
+ if err := t .validate (validateMinLength ,
362
+ validateMaxLenth ,
363
+ validateMaxDepth ); err != nil {
364
+ r .setError (err )
365
+ return r
366
+ }
367
+
343
368
if dMode , ok := t .getOption ("delivery_mode" ); ok {
344
369
val , err := strconv .ParseInt (dMode , 10 , 64 )
345
370
if err == nil {
@@ -419,6 +444,15 @@ func (c *client) Relay(topics []string, relOpts ...RelOptions) Result {
419
444
return r
420
445
}
421
446
447
+ if err := t .validate (validateMinLength ,
448
+ validateMaxLenth ,
449
+ validateMaxDepth ,
450
+ validateMultiWildcard ,
451
+ validateTopicParts ); err != nil {
452
+ r .setError (err )
453
+ return r
454
+ }
455
+
422
456
if dur , ok := t .getOption ("last" ); ok {
423
457
last = dur
424
458
}
@@ -475,6 +509,15 @@ func (c *client) Subscribe(subTopic string, subOpts ...SubOptions) Result {
475
509
return r
476
510
}
477
511
512
+ if err := t .validate (validateMinLength ,
513
+ validateMaxLenth ,
514
+ validateMaxDepth ,
515
+ validateMultiWildcard ,
516
+ validateTopicParts ); err != nil {
517
+ r .setError (err )
518
+ return r
519
+ }
520
+
478
521
if dMode , ok := t .getOption ("delivery_mode" ); ok {
479
522
val , err := strconv .ParseInt (dMode , 10 , 64 )
480
523
if err == nil {
@@ -540,6 +583,15 @@ func (c *client) SubscribeMultiple(topics []string, subOpts ...SubOptions) Resul
540
583
return r
541
584
}
542
585
586
+ if err := t .validate (validateMinLength ,
587
+ validateMaxLenth ,
588
+ validateMaxDepth ,
589
+ validateMultiWildcard ,
590
+ validateTopicParts ); err != nil {
591
+ r .setError (err )
592
+ return r
593
+ }
594
+
543
595
if dMode , ok := t .getOption ("delivery_mode" ); ok {
544
596
val , err := strconv .ParseInt (dMode , 10 , 64 )
545
597
if err == nil {
@@ -725,7 +777,7 @@ func (c *client) isClosed() bool {
725
777
// Check read ok status.
726
778
func (c * client ) ok () error {
727
779
if c .isClosed () {
728
- return errors .New ("client connection is closed. " )
780
+ return errors .New ("client connection is closed" )
729
781
}
730
782
return nil
731
783
}
0 commit comments