๐ Manage single active WebSocket connections per user with Redis-powered persistence.
https://github.com/IamLizu/sockmanage.git
SockManage is a utility library for managing WebSocket connections, ensuring each user has a single active socket connection at any given time. It uses Redis for persistence, making it suitable for scalable and distributed WebSocket applications.
To install with npm:
npm install sockmanage
or with Yarn:
yarn add sockmanage
import { createClient } from "redis";
import { Server as SocketIOServer } from "socket.io";
import { SockManage } from "sockmanage";
// Initialize Redis and Socket.IO
const redisClient = createClient();
const io = new SocketIOServer(server); // assume 'server' is an HTTP server
// Initialize SockManage
const socketManager = new SockManage({ redis: redisClient });
// Set up the Socket.IO server and specify the namespace (optional)
socketManager.setup({ io, namespace: "/your-namespace" });
// Assuming top-level await is supported, otherwise wrap the following line in an async function
await socketManager.initialize();
setupSets up Socket.IO server and optional namespace.
socketManager.setup({ io, namespace: "/your-namespace" });
Parameters:
io: Instance of SocketIOServer.namespace (optional): Namespace for Socket.IO events.initializeInitializes user sockets from Redis.
await socketManager.initialize();
getSocketsRetrieves all user sockets from local map.
const userSockets = socketManager.getSockets();
Returns: Map<string, string>: A map of user IDs to socket IDs, or an empty map.
getSocketRetrieves the socket ID for a specific user.
const socketId = socketManager.getSocket("userId");
Parameters:
userId: ID of the user.string | null: Socket ID of the user or null if not found.
registerRegisters a socket for a user and ensures only one active socket per user.
Note: The data parameter must be a JSON string containing the userId.
await socketManager.register(socket, JSON.stringify({ userId: "user1" }));
Parameters:
socket: The socket instance.data: A JSON string containing the userId.deRegisterDe-registers a socket for a user.
socketManager.deRegister(socket);
Parameters:
socket: The socket instance to deregister.informEmits an event to a specific socket.
socketManager.inform({
socketId: "socket1",
_event: "message",
data: { message: "Hello, User!" },
});
Parameters:
socketId: ID of the socket to emit the event to._event: Event name.data: Data to send with the event.import { createClient } from "redis";
import { Server as SocketIOServer } from "socket.io";
import { SockManage } from "sockmanage";
const redisClient = createClient();
const io = new SocketIOServer(server);
const socketManager = new SockManage({ redis: redisClient });
socketManager.setup({ io });
// Assuming top-level await is supported, otherwise wrap the following line in an async function
await socketManager.initialize();
io.on("connection", (socket) => {
// You be getting the userId from anywhere, it doesn't matter where you get it from
// as long as you pass it to the register method.
const userId = socket.handshake.query.userId;
socketManager.register(socket, JSON.stringify({ userId }));
socket.on("disconnect", () => {
socketManager.deRegister(socket);
});
// this following block is completely optional, you shall proceed with using your own event sending logic
socket.on("message", (data) => {
socketManager.inform({
socketId: socket.id,
_event: "message",
data: { message: "Hello, User!" },
});
});
});
To run the tests, use the following command:
yarn test
Detailed changes for each version are documented in the History.md file.
MIT License. See LICENSE for details.