-
Architecture:
-
Each of the
u_k
's connects to web-socket server as normal. -
For each of
ws_k
's, they still rely onroom
'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 bothws_1
andws_2
. u_1
joinroom_1
viaws_1
andu_2
joinroom_1
viaws_2
.
- For example,
-
Fun part. Now each of the
ws_k
servers registerspublish
andsubscribe
listeners toredis
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!
Scaling Websocket Chat Sever by Redis