@@ -102,8 +102,10 @@ export class RedisAdapter extends Adapter {
102
102
private readonly channel : string ;
103
103
private readonly requestChannel : string ;
104
104
private readonly responseChannel : string ;
105
+ private readonly specificResponseChannel : string ;
105
106
private requests : Map < string , Request > = new Map ( ) ;
106
107
private ackRequests : Map < string , AckRequest > = new Map ( ) ;
108
+ private redisListeners : Map < string , Function > = new Map ( ) ;
107
109
108
110
/**
109
111
* Adapter constructor.
@@ -133,34 +135,51 @@ export class RedisAdapter extends Adapter {
133
135
this . channel = prefix + "#" + nsp . name + "#" ;
134
136
this . requestChannel = prefix + "-request#" + this . nsp . name + "#" ;
135
137
this . responseChannel = prefix + "-response#" + this . nsp . name + "#" ;
136
- const specificResponseChannel = this . responseChannel + this . uid + "#" ;
138
+ this . specificResponseChannel = this . responseChannel + this . uid + "#" ;
137
139
138
140
const isRedisV4 = typeof this . pubClient . pSubscribe === "function" ;
139
141
if ( isRedisV4 ) {
142
+ this . redisListeners . set ( "psub" , ( msg , channel ) => {
143
+ this . onmessage ( null , channel , msg ) ;
144
+ } ) ;
145
+
146
+ this . redisListeners . set ( "sub" , ( msg , channel ) => {
147
+ this . onrequest ( channel , msg ) ;
148
+ } ) ;
149
+
140
150
this . subClient . pSubscribe (
141
151
this . channel + "*" ,
142
- ( msg , channel ) => {
143
- this . onmessage ( null , channel , msg ) ;
144
- } ,
152
+ this . redisListeners . get ( "psub" ) ,
145
153
true
146
154
) ;
147
155
this . subClient . subscribe (
148
- [ this . requestChannel , this . responseChannel , specificResponseChannel ] ,
149
- ( msg , channel ) => {
150
- this . onrequest ( channel , msg ) ;
151
- } ,
156
+ [
157
+ this . requestChannel ,
158
+ this . responseChannel ,
159
+ this . specificResponseChannel ,
160
+ ] ,
161
+ this . redisListeners . get ( "sub" ) ,
152
162
true
153
163
) ;
154
164
} else {
165
+ this . redisListeners . set ( "pmessageBuffer" , this . onmessage . bind ( this ) ) ;
166
+ this . redisListeners . set ( "messageBuffer" , this . onrequest . bind ( this ) ) ;
167
+
155
168
this . subClient . psubscribe ( this . channel + "*" ) ;
156
- this . subClient . on ( "pmessageBuffer" , this . onmessage . bind ( this ) ) ;
169
+ this . subClient . on (
170
+ "pmessageBuffer" ,
171
+ this . redisListeners . get ( "pmessageBuffer" )
172
+ ) ;
157
173
158
174
this . subClient . subscribe ( [
159
175
this . requestChannel ,
160
176
this . responseChannel ,
161
- specificResponseChannel ,
177
+ this . specificResponseChannel ,
162
178
] ) ;
163
- this . subClient . on ( "messageBuffer" , this . onrequest . bind ( this ) ) ;
179
+ this . subClient . on (
180
+ "messageBuffer" ,
181
+ this . redisListeners . get ( "messageBuffer" )
182
+ ) ;
164
183
}
165
184
166
185
const registerFriendlyErrorHandler = ( redisClient ) => {
@@ -917,4 +936,49 @@ export class RedisAdapter extends Adapter {
917
936
serverCount ( ) : Promise < number > {
918
937
return this . getNumSub ( ) ;
919
938
}
939
+
940
+ close ( ) : Promise < void > | void {
941
+ const isRedisV4 = typeof this . pubClient . pSubscribe === "function" ;
942
+ if ( isRedisV4 ) {
943
+ this . subClient . pUnsubscribe (
944
+ this . channel + "*" ,
945
+ this . redisListeners . get ( "psub" ) ,
946
+ true
947
+ ) ;
948
+
949
+ // There is a bug in redis v4 when unsubscribing multiple channels at once, so we'll unsub one at a time.
950
+ // See https://github.com/redis/node-redis/issues/2052
951
+ this . subClient . unsubscribe (
952
+ this . requestChannel ,
953
+ this . redisListeners . get ( "sub" ) ,
954
+ true
955
+ ) ;
956
+ this . subClient . unsubscribe (
957
+ this . responseChannel ,
958
+ this . redisListeners . get ( "sub" ) ,
959
+ true
960
+ ) ;
961
+ this . subClient . unsubscribe (
962
+ this . specificResponseChannel ,
963
+ this . redisListeners . get ( "sub" ) ,
964
+ true
965
+ ) ;
966
+ } else {
967
+ this . subClient . punsubscribe ( this . channel + "*" ) ;
968
+ this . subClient . off (
969
+ "pmessageBuffer" ,
970
+ this . redisListeners . get ( "pmessageBuffer" )
971
+ ) ;
972
+
973
+ this . subClient . unsubscribe ( [
974
+ this . requestChannel ,
975
+ this . responseChannel ,
976
+ this . specificResponseChannel ,
977
+ ] ) ;
978
+ this . subClient . off (
979
+ "messageBuffer" ,
980
+ this . redisListeners . get ( "messageBuffer" )
981
+ ) ;
982
+ }
983
+ }
920
984
}
0 commit comments