redis / ioredis

🚀 A robust, performance-focused, and full-featured Redis client for Node.js.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Are you able to have 2 connections for 2 separate servers open at the same time?

dills122 opened this issue · comments

I'm working on a chat app with Nest.js and initially had a RedisIoAdapter.ts setup after reading some docs, and that is/was working fine. However, when I added another Redis instance & client I started to get the error.

Error: Redis is already connecting/connected

So its leading me to believe I can't have connections open for each of my two servers?

Overview of what I'm trying to do:

  • Server 1 (port 6379) - Pub/Sub IO Adapter
  • Server 2 (port 6380) - Meta-data cache for sessions

Server 1 gets its connection setup in the bootstrap method for the NestJS server. Then Server 2 gets setup in the RedisModule with its client.factory`.

If I disable one of them (IOAdapter is the easiest to disable/comment out) then it runs without an error, but if I start the app with both still enabled, I get the error above whenever the second connection trys to start.

Server 2 Client Factory:

import { FactoryProvider } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import Redis from 'ioredis';

export const redisClientFactory: FactoryProvider<Redis> = {
  provide: 'RedisClient',
  useFactory: (configService: ConfigService) => {
    const redisInstance = new Redis({
      port: configService.get('REDIS_DB_PORT'),
      host: configService.get('REDIS_DB_HOST')
    });

    redisInstance.on('error', (e) => {
      throw new Error(`Redis connection failed: ${e}`);
    });

    return redisInstance;
  },
  inject: [ConfigService]
};

Server 1 IOAdapter:

import { IoAdapter } from '@nestjs/platform-socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { Redis } from 'ioredis';
import { Server, ServerOptions } from 'socket.io';
import * as util from '../shared/util';

import { INestApplicationContext } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

const host = util.isLocal() ? 'localhost' : 'redis';

export class RedisIoAdapter extends IoAdapter {
  protected redisAdapter;

  constructor(private app: INestApplicationContext) {
    super(app);
    const configService = this.app.get(ConfigService);
    const port: string = configService.get('REDIS_IO_PORT') || '';
    if (!port || port.length <= 0 || !host) {
      throw Error('Issue creating the Redis URL');
    }
    const pubClient = new Redis({
      host,
      port: Number(port)
    });
    const subClient = pubClient.duplicate();

    pubClient.connect(); // <------
    subClient.connect(); // <------

    this.redisAdapter = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions) {
    const server = super.createIOServer(port, options) as Server;

    server.adapter(this.redisAdapter);

    return server;
  }
}
import { IoAdapter } from '@nestjs/platform-socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { Redis } from 'ioredis';
import { Server, ServerOptions } from 'socket.io';
import * as util from '../shared/util';

import { INestApplicationContext } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';

const host = util.isLocal() ? 'localhost' : 'redis';

export class RedisIoAdapter extends IoAdapter {
  protected redisAdapter;

  constructor(private app: INestApplicationContext) {
    super(app);
    const configService = this.app.get(ConfigService);
    const port: string = configService.get('REDIS_IO_PORT') || '';
    if (!port || port.length <= 0 || !host) {
      throw Error('Issue creating the Redis URL');
    }
    const pubClient = new Redis({
      host,
      port: Number(port)
    });   
   //Create a new instance and initiate them individually 
    const subClient = new Redis({
      host,
      port:Number(port)
})

    pubClient.connect(); // <------
    subClient.connect(); // <------

    this.redisAdapter = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions) {
    const server = super.createIOServer(port, options) as Server;

    server.adapter(this.redisAdapter);

    return server;
  }
}

If want to duplicate the same instance

 const subClient = new Redis({
      host,
      port:Number(port)
})
const pubClient=subClient.duplicate();
subClient.connect()

The pubClient is automatically connect (before call subClient.connect())