@@ -102,8 +102,10 @@ export class RedisAdapter extends Adapter {
102102 private readonly channel : string ;
103103 private readonly requestChannel : string ;
104104 private readonly responseChannel : string ;
105+ private readonly specificResponseChannel : string ;
105106 private requests : Map < string , Request > = new Map ( ) ;
106107 private ackRequests : Map < string , AckRequest > = new Map ( ) ;
108+ private redisListeners : Map < string , Function > = new Map ( ) ;
107109
108110 /**
109111 * Adapter constructor.
@@ -133,34 +135,51 @@ export class RedisAdapter extends Adapter {
133135 this . channel = prefix + "#" + nsp . name + "#" ;
134136 this . requestChannel = prefix + "-request#" + this . nsp . name + "#" ;
135137 this . responseChannel = prefix + "-response#" + this . nsp . name + "#" ;
136- const specificResponseChannel = this . responseChannel + this . uid + "#" ;
138+ this . specificResponseChannel = this . responseChannel + this . uid + "#" ;
137139
138140 const isRedisV4 = typeof this . pubClient . pSubscribe === "function" ;
139141 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+
140150 this . subClient . pSubscribe (
141151 this . channel + "*" ,
142- ( msg , channel ) => {
143- this . onmessage ( null , channel , msg ) ;
144- } ,
152+ this . redisListeners . get ( "psub" ) ,
145153 true
146154 ) ;
147155 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" ) ,
152162 true
153163 ) ;
154164 } else {
165+ this . redisListeners . set ( "pmessageBuffer" , this . onmessage . bind ( this ) ) ;
166+ this . redisListeners . set ( "messageBuffer" , this . onrequest . bind ( this ) ) ;
167+
155168 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+ ) ;
157173
158174 this . subClient . subscribe ( [
159175 this . requestChannel ,
160176 this . responseChannel ,
161- specificResponseChannel ,
177+ this . specificResponseChannel ,
162178 ] ) ;
163- this . subClient . on ( "messageBuffer" , this . onrequest . bind ( this ) ) ;
179+ this . subClient . on (
180+ "messageBuffer" ,
181+ this . redisListeners . get ( "messageBuffer" )
182+ ) ;
164183 }
165184
166185 const registerFriendlyErrorHandler = ( redisClient ) => {
@@ -917,4 +936,49 @@ export class RedisAdapter extends Adapter {
917936 serverCount ( ) : Promise < number > {
918937 return this . getNumSub ( ) ;
919938 }
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+ }
920984}
0 commit comments