Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work with redis "createCluster" throw a TypeError: this.subClient.psubscribe is not a function #484

Closed
March-mitsuki opened this issue Jan 16, 2023 · 2 comments

Comments

@March-mitsuki
Copy link

Hello, I'm using the following versions of socket.io and redis, with Node.js v18.13.0

    "@socket.io/redis-adapter": "^8.0.1",
    "express": "^4.18.2",
    "redis": "^4.5.1",
    "socket.io": "^4.5.4",

I have written the following test code based on the documentation https://socket.io/docs/v4/redis-adapter/ and https://github.com/redis/node-redis/blob/master/docs/clustering.md.

import express from "express";
import http from "http";
import { Server as SocketServer } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createCluster } from "redis";

const app = express();
  const server = http.createServer(app);
  const sio = new SocketServer(server);

  const pub = createCluster({
    rootNodes: [
      { url: "redis://192.168.64.1:6379", password: "password" },
      { url: "redis://192.168.64.2:6379", password: "password" },
      { url: "redis://192.168.64.3:6379", password: "password" },
    ],
  });
  const sub = pub.duplicate();

  pub.on("error", (err) => {
    console.log(`[err] PUB redis cluster: ${err}`);
    throw new Error("redis cluster error");
  });
  sub.on("error", (err) => {
    console.log(`[err] SUB redis cluster: ${err}`);
    throw new Error("redis cluster error");
  });

  await pub.connect();
  await sub.connect();

  sio.adapter(createAdapter(pub, sub));

  sio.on("connection", (socket) => {
    console.log(`hello: ${socket.id}`);

    socket.on("disconnect", () => {
      console.log(`goodbye: ${socket.id}`);
    });

    socket.onAny((evt, data) => {
      console.log(`from: ${socket.id}`, `- [${evt}]: ${data}`);
    });
  });

  app.get("/ping", (req, res) => {
    res.send("pong");
    return;
  });

  server.listen(5139, () => {
    console.log("server is listen on: 5139");
  });

But when I run this code, I get a TypeError:

TypeError: this.subClient.psubscribe is not a function
    at new RedisAdapter (/path/to/project/node_modules/@socket.io/redis-adapter/dist/index.js:88:28)
    at new <anonymous> (/path/to/project/node_modules/@socket.io/redis-adapter/dist/index.js:48:16)
    at Namespace._initAdapter (/path/to/project/node_modules/socket.io/dist/namespace.js:93:24)
    at Server.adapter (/path/to/project/node_modules/socket.io/dist/index.js:166:17)
    at initServer (file:///path/to/project/src/server.js:35:7)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v18.13.0

I have tested this cluster pubsub with redis-cli and everything works fine when using redis-cli -c.

When I don't use createCluster and switch to use createClient everything works fine.

- const pub = createCluster({
-   rootNodes: [
-     { url: "redis://192.168.64.1:6379", password: "password" },
-     { url: "redis://192.168.64.2:6379", password: "password" },
-     { url: "redis://192.168.64.3:6379", password: "password" },
-   ],
- });

+ const pub = createClient({
+   url: "redis://localhost:6379",
+   password: "password",
+ });

When I run this code, everything looks ok.

This is very strange, can anyone help me?

@darrachequesne
Copy link
Member

Hi! It seems the redis package does not currently support PUB/SUB within a cluster: redis/node-redis#2065

I think you will have to use the ioredis package for now:

const io = require('socket.io')(3000);
const redisAdapter = require('@socket.io/redis-adapter');
const Redis = require('ioredis');

const startupNodes = [
  {
    port: 6380,
    host: '127.0.0.1'
  },
  {
    port: 6381,
    host: '127.0.0.1'
  }
];

const pubClient = new Redis.Cluster(startupNodes);
const subClient = pubClient.duplicate();

io.adapter(redisAdapter(pubClient, subClient));

@March-mitsuki
Copy link
Author

@darrachequesne I switch to use ioredis, everything works fine. Thankyou! ☺️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants