0%
September 20, 2023

Scaling Websocket Chat Sever by Redis

nodejs

redis

web-socket

  • Architecture:

  • Each of the u_k's connects to web-socket server as normal.

  • For each of ws_k's, they still rely on room's for publishing messages within a group of sockets.

  • Same room can repeatedly appears in each of the socket servers.

    • For example, room_1 can appear in both ws_1 and ws_2.
    • u_1 join room_1 via ws_1 and u_2 join room_1 via ws_2.
  • Fun part. Now each of the ws_k servers registers publish and subscribe listeners to redis server.

    Note that the following code can be executed right before app.listen().

    1// ws_k
    2// pubsubWithIo.ts
    3// to be run right before `app.listen()`;
    4
    5import redis from "redis";
    6
    7const subscriber = redis.createClient({
    8  port: 6379,
    9  host: redis_url,
    10});
    11
    12export const publisher = redis.createClient({
    13  port: 6379,
    14  host: redis_url,
    15});
    16const io = getIoSingletonFromSomewhere();
    17
    18subscriber.on("subscribe", function (channel, count) {
    19  // do something, or even omit this listener
    20});
    21
    22export type Message = {
    23  namespace: string,
    24  roomCode: string,
    25  msg:{ sender:string, text: string }
    26}
    27subscriber.on("message", function (_channel: string, message: Message) {
    28  try {
    29    const { namespace, roomCode, msg } = message;
    30    io.of(namespace).to(roomCode).emit("MSG_TO_CLIENTS", msg);
    31  } catch (err) {
    32    consol.log(err);
    33  }
    34});
    35
    36subscriber.subscribe("livechat");

    Finally we also have a publish event, this is supposed to be wrapped inside a post request:

    // ws_k
    
    import { publisher, Message } from `some/where/pubsubWithIo`;
    ...
    router.post("/some-outer-route", async (req, res) => {
      const msg = req.body as Message;
      publisher.publish("livechat", msg);
      res.json({ success: true });
    });
  • Now we easily scaled up the a chat server!

Referenece