import { Redis } from "ioredis" ; import * as winston from "winston" ; import { Lumberjack } from "@fluidframework/server-services-telemetry" ; import { ISocketIoRedisConnection , ISocketIoRedisSubscriptionConnection } from "./redisSocketIoAdapter" ; /**
 * Simple implementation of ISocketIoRedisConnection, which wraps a redis client
 * and only provides Pub functionality
 */ export class SocketIORedisConnection implements ISocketIoRedisConnection { constructor ( protected readonly client ) { client . on ( "error" , ( err ) => { winston . error ( "Error with Redis:" , err ) ; Lumberjack . error ( "Error with Redis:" , undefined , err ) ; } ) ; } public async publish ( channel , message ) { await this . client . publish ( channel , message ) ; } } /**
 * Simple implementation of ISocketIoRedisSubscriptionConnection, which wraps a node-redis client
 * and provides both pub and sub functionality
 */ export class SocketIoRedisSubscriptionConnection extends SocketIORedisConnection implements ISocketIoRedisSubscriptionConnection { /**
     * Map of pubsub callbacks
     */ private readonly subscriptions : Map < string , ( channel : string , messageBuffer : Buffer ) => void > = new Map ( ) ; constructor ( client ) { super ( client ) ; client . on ( "messageBuffer" , ( channelBuffer , messageBuffer ) => { const channel = channelBuffer . toString ( ) ; const callback = this . subscriptions . get ( channel ) ; if ( ! callback ) { return ; } callback ( channel , messageBuffer ) ; } ) ; } public async subscribe ( channels , callback , forceSubscribe ? ) { let channelsArray = Array . isArray ( channels ) ? channels : [ channels ] ; const subscriptionsMap = this . subscriptions ; if ( ! forceSubscribe ) { channelsArray = channelsArray . filter ( ( channel ) => ! subscriptionsMap . has ( channel ) ) ; if ( channelsArray . length === 0 ) { return ; } } await this . client . subscribe ( ... channelsArray ) ; for ( const channel of channelsArray ) { subscriptionsMap . set ( channel , callback ) ; } } public async unsubscribe ( channels ) { let channelsArray = Array . isArray ( channels ) ? channels : [ channels ] ; const subscriptionsMap = this . subscriptions ; channelsArray = channelsArray . filter ( ( channel ) => subscriptionsMap . has ( channel ) ) ; if ( channelsArray . length === 0 ) { return ; } await this . client . unsubscribe ( channelsArray ) ; for ( const channel of channelsArray ) { subscriptionsMap . delete ( channel ) ; } } public isSubscribed ( channel ) { return this . subscriptions . has ( channel ) ; } }