11
11
use Clue \Redis \Protocol \Factory as ProtocolFactory ;
12
12
use UnderflowException ;
13
13
use RuntimeException ;
14
+ use InvalidArgumentException ;
14
15
use React \Promise \Deferred ;
15
16
use Clue \Redis \Protocol \Model \ErrorReply ;
16
17
use Clue \Redis \Protocol \Model \ModelInterface ;
@@ -77,18 +78,43 @@ public function __call($name, $args)
77
78
{
78
79
$ request = new Deferred ();
79
80
81
+ $ name = strtolower ($ name );
82
+
83
+ // special (p)(un)subscribe commands only accept a single parameter and have custom response logic applied
84
+ static $ pubsubs = array ('subscribe ' , 'unsubscribe ' , 'psubscribe ' , 'punsubscribe ' );
85
+
80
86
if ($ this ->ending ) {
81
87
$ request ->reject (new RuntimeException ('Connection closed ' ));
88
+ } elseif (count ($ args ) !== 1 && in_array ($ name , $ pubsubs )) {
89
+ $ request ->reject (new InvalidArgumentException ('PubSub commands limited to single argument ' ));
82
90
} else {
83
91
$ this ->stream ->write ($ this ->serializer ->getRequestMessage ($ name , $ args ));
84
92
$ this ->requests []= $ request ;
85
93
}
86
94
87
- if (strtolower ( $ name) === 'monitor ' ) {
95
+ if ($ name === 'monitor ' ) {
88
96
$ monitoring =& $ this ->monitoring ;
89
97
$ request ->then (function () use (&$ monitoring ) {
90
98
$ monitoring = true ;
91
99
});
100
+ } elseif (in_array ($ name , $ pubsubs )) {
101
+ $ that = $ this ;
102
+ $ subscribed =& $ this ->subscribed ;
103
+ $ psubscribed =& $ this ->psubscribed ;
104
+
105
+ $ request ->then (function ($ array ) use ($ that , &$ subscribed , &$ psubscribed ) {
106
+ $ first = array_shift ($ array );
107
+
108
+ // (p)(un)subscribe messages are to be forwarded
109
+ $ that ->emit ($ first , $ array );
110
+
111
+ // remember number of (p)subscribe topics
112
+ if ($ first === 'subscribe ' || $ first === 'unsubscribe ' ) {
113
+ $ subscribed = $ array [1 ];
114
+ } else {
115
+ $ psubscribed = $ array [1 ];
116
+ }
117
+ });
92
118
}
93
119
94
120
return $ request ->promise ();
@@ -103,17 +129,13 @@ public function handleMessage(ModelInterface $message)
103
129
return ;
104
130
}
105
131
106
- if (/* ($this->subscribed !== 0 || $this->psubscribed !== 0) &&*/ $ message instanceof MultiBulkReply) {
132
+ if (($ this ->subscribed !== 0 || $ this ->psubscribed !== 0 ) && $ message instanceof MultiBulkReply) {
107
133
$ array = $ message ->getValueNative ();
108
134
$ first = array_shift ($ array );
109
135
110
- // pub/sub events are to be forwarded
111
- if (in_array ($ first , array ('message ' , 'subscribe ' , 'unsubscribe ' , 'pmessage ' , 'psubscribe ' , 'punsubscribe ' ))) {
112
- $ this ->emit ($ first , $ array );
113
- }
114
-
115
- // pub/sub message events should not be processed as request responses
136
+ // pub/sub messages are to be forwarded and should not be processed as request responses
116
137
if (in_array ($ first , array ('message ' , 'pmessage ' ))) {
138
+ $ this ->emit ($ first , $ array );
117
139
return ;
118
140
}
119
141
}
0 commit comments