A Place Where Random People Meet And Chat.
1
2import { createClient } from "redis";
3
4export const address = new Map();
5
6export const redis = createClient({
7 socket: { host: "127.0.0.1", port: 6379 }
8});
9
10redis.on("error", (err) => console.error("Redis error:", err));
11redis.on("end", () => console.warn("Redis connection closed"));
12
13redis.connect()
14 .then(() => console.log("Connected to Redis"))
15 .catch((err) => console.error("Redis connection error:", err));
16
17export const addUser = async (user, socket) => {
18 await redis.sAdd("activeUsers", user);
19 address.set(user, socket);
20};
21
22export const removeUser = async (user) => {
23 const friend = await redis.hGet("friends", user);
24
25 await redis.sRem("activeUsers", user);
26 await redis.hDel("friends", user);
27 address.delete(user);
28
29 if (friend) {
30 await redis.hDel("friends", friend);
31 await redis.sAdd("activeUsers", friend);
32 const friendSocket = address.get(friend);
33 if (friendSocket) {
34 friendSocket.send(JSON.stringify({ type: "disconnected" }));
35 }
36 }
37};
38
39
40
41export const getRandom = async (user) => {
42 const TIMEOUT_MS = 10000;
43 const INTERVAL_MS = 500;
44 const start = Date.now();
45
46 const existing = await redis.hGet("friends", user);
47 if (existing) return existing;
48
49 while (Date.now() - start < TIMEOUT_MS) {
50
51 const existing = await redis.hGet("friends", user);
52 if (existing) return existing;
53
54 const friend = await redis.sRandMember("activeUsers");
55 if (!friend || friend === user) {
56 await new Promise(r => setTimeout(r, INTERVAL_MS));
57 continue;
58 }
59
60 await redis.watch(`friends:${user}`, `friends:${friend}`);
61 const [userPaired, friendPaired] = await redis.hmGet("friends", user, friend);
62
63 if (userPaired || friendPaired) {
64 await redis.unwatch();
65 await new Promise(r => setTimeout(r, INTERVAL_MS));
66 continue;
67 }
68
69 const tx = redis.multi();
70 tx.hSet("friends", user, friend);
71 tx.hSet("friends", friend, user);
72 tx.sRem("activeUsers", user);
73 tx.sRem("activeUsers", friend);
74
75 const result = await tx.exec();
76 if (result) {
77 return friend;
78 }
79
80 await new Promise(r => setTimeout(r, INTERVAL_MS));
81 }
82
83 return null;
84};
85
86
87export const addMessage = async (payload, user, type) => {
88 const friend = await redis.hGet("friends", user);
89 if (!friend) return;
90
91 const field = `${user}:${friend}:${type}`;
92 await redis.rPush(field, JSON.stringify(payload));
93 await redis.expire(field, 3600); // 1 hour expiry
94};
95
96
97export const getMessages = async (user, friend, type) => {
98 const field = `${user}:${friend}:${type}`;
99 const messages = await redis.lRange(field, 0, -1); // Get all messages
100 return messages.map(msg => JSON.parse(msg)); // Return list of JSON objects
101};
102
103export const getTime = () => new Date().toISOString();
104