Skip to content

Commit

Permalink
feat: use redis for sessions
Browse files Browse the repository at this point in the history
  • Loading branch information
lewxdev committed Aug 21, 2024
1 parent fc6bf5a commit f179975
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 15 deletions.
12 changes: 6 additions & 6 deletions app/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import next from "next";
import { Server } from "socket.io";
import type { SocketServer } from "@/types";
import { Field } from "@/utils/game";
import * as redis from "@/utils/redis";

const dev = process.env.NODE_ENV !== "production";
const hostname = "localhost";
const port = 3000;
const sessions = new Map<string, "alive" | "dead">();

async function main() {
const app = next({ dev, hostname, port });
Expand All @@ -24,8 +24,8 @@ async function main() {

io.use(async (socket, next) => {
const { sessionId } = socket.handshake.auth;
const sessionState = sessions.get(sessionId);
if (sessions.get(sessionId) === "dead") {
const sessionState = await redis.getSession(sessionId);
if (sessionState === "dead") {
return next(new Error("dead"));
}
socket.data.sessionId = sessionState
Expand All @@ -34,8 +34,8 @@ async function main() {
next();
});

io.on("connection", (socket) => {
sessions.set(socket.data.sessionId, "alive");
io.on("connection", async (socket) => {
await redis.startSession(socket.data.sessionId);
socket.emit("sessionAlive", socket.data.sessionId);

clientsCount++;
Expand All @@ -45,7 +45,7 @@ async function main() {

socket.on("expose", async (index) => {
if (field.exposeCell(index) === "dead") {
sessions.set(socket.data.sessionId, "dead");
await redis.killSession(socket.data.sessionId);
socket.emit("sessionDead");
} else {
field = await field.handleComplete();
Expand Down
34 changes: 25 additions & 9 deletions app/utils/redis.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
import { Redis } from "ioredis";
import _ from "lodash";

const key = "field:data";
const fieldKey = "field:data";
const sessionKey = "user:sessions";

function getClient() {
return new Redis(process.env["REDIS_URL"]!, { family: 6 });
}
const redis = new Redis(process.env["REDIS_URL"]!, { family: 6 });

export async function decodeData() {
const redis = getClient();
const value = await redis.get(key);
const value = await redis.get(fieldKey);
if (typeof value !== "string" || !value) {
throw new Error(`unexpected data on key: ${key}`);
throw new Error(`unexpected data on key: ${fieldKey}`);
}
return Array.from(value, (char) => char.charCodeAt(0));
}

export async function encodeData(value: number[]) {
const redis = getClient();
const binaryString = Buffer.from(value).toString("binary");
await redis.set(key, binaryString);
await redis.set(fieldKey, binaryString);
return value;
}

export async function getSession(sessionId: string) {
const value = await redis.hget(sessionKey, sessionId);
return value === "alive" || value === "dead" ? value : null;
}

export async function startSession(sessionId: string) {
return redis.hset(sessionKey, sessionId, "alive");
}

export async function killSession(sessionId: string) {
return redis.hset(sessionKey, sessionId, "dead");
}

export async function reviveSessions() {
const sessions = await redis.hkeys(sessionKey);
const args = sessions.flatMap((sessionId) => [sessionId, "alive"]);
redis.hset(sessionKey, ...args);
}

0 comments on commit f179975

Please sign in to comment.