Socket.IO in Meetzy
Step-by-step Guide
This section explains how real-time communication works inside Meetzy. It covers the complete socket flow — from connecting users to updating chats, presence, and calls. Snippets are ready to copy and use. Meetzy ships with all required packages; running npm install in each folder sets everything up.
Quick overview:
Frontend creates a socket connection. Backend authenticates it, places users in rooms, and
broadcasts chat events in real time.
Pattern: connect → authenticate → join rooms → emit/listen → cleanup.
Prerequisites
Node.js + npm installed.
-
Environment variable for socket URL: VITE_SOCKET_URL in frontend and configured server URL in backend.
-
Meetzy includes socket.io (server) and socket.io-client (client). No separate installation needed beyond npm install.
Create a reusable socket instance
Meetzy uses a single shared socket instance across the app.
- // src/services/socket.ts
- import { io } from "socket.io-client";
- export const socket = io(import.meta.env.VITE_SOCKET_URL, {
- transports: ["polling"],
- reconnectionAttempts: 3,
- reconnectionDelay: 1000,
- timeout: 30000,
- });
Notes:
-
-autoConnect: false if you want to attach auth before connecting.
-
-transports controls fallback behavior.
-
-reconnection* options improve stability.
Frontend: connect and authenticate
Meetzy connects only after login so chats, presence, and calls sync instantly.
- // src/providers/SocketProvider.tsx (concept)
- useEffect(() => {
- if (!user || !token) return;
- socket.auth = { token };
- socket.connect();
- socket.emit("join_room", user.id);
- return () => socket.disconnect();
- }, [user, token]);
Tips:
-
-Attach token through socket.auth for verification.
-Always unregister listeners during cleanup.
Frontend: listening and emitting
Meetzy uses small isolated handlers for messages, media, and presence.
- // listener
- socket.on("receive_message", (msg) => { /* update store */ });
- // emit
- socket.emit("send_message", { chatId, text });
- Cleanup: socket.off("receive_message");
Recommended: centralize socket logic in a hook like useChatSocket().
Backend: minimal server
Meetzy uses room-based routing for faster message delivery.
- // server.js (concept)
- const httpServer = require("http").createServer(app);
- const { Server } = require("socket.io");
- const io = new Server(httpServer, { cors: { origin: "*" } });
- io.on("connection", (socket) => {
- console.log("connected", socket.id);
- socket.on("join_room", (userId) => {
- socket.join(`user_${userId}`);
- });
- socket.on("send_message", (payload) => {
- io.to(`user_${payload.recipientId}`).emit("receive_message", payload);
- });
- });
Notes:
-
Use socket.join for user rooms or chat rooms.
-
io.to(room).emit() sends events instantly.
Validate tokens and payloads server-side.
Common event map
Meetzy uses consistent event names across chat, media, and calls.
-
Client → Server
-
join_room (userId)
-
send_message (text/media payload)
-
typing:start / typing:stop
-
mark_seen (messageId)
-
Server → Client
-
receive_message
-
message_status_update
-
typing_update
-
user_presence
Presence and heartbeat
Meetzy updates online/offline status using periodic heartbeats.
- // client-side
- const heartbeat = setInterval(() => {
- if (socket.connected) socket.emit("presence_ping");
- }, 5 * 60 * 1000);
- clearInterval(heartbeat);
Server updates last-seen and broadcasts presence to relevant rooms.
Reliability and reconnection
Handle unstable networks gracefully.
- socket.on("connect_error", (err) => {
- console.warn("socket error", err);
- });
Security best practices
-
Authenticate using JWT in socket.handshake.auth.
Authorize each event server-side.
Configure strict CORS.
Throttle events like typing or reactions.
Use HTTPS/WSS in production.
Sanitize user-generated strings.
Adding custom logic
Typing Indicator
- // client
- socket.emit("typing:start", { chatId });
- // server
- socket.to(`chat_${chatId}`).emit("typing:start", { userId });
Media Upload Progress
-
Client uploads and emits upload:progress.
Recipients see progress in real time.
Integrating with app state
-Update UI with Redux/React Query.
-Use setQueryData() to insert new messages.
-Ensure idempotent updates.
Debugging & testing tips
-Check socket.connection, id, and transport in console.
-Review server logs for joins/emits.
-Use a simple HTML test client during development.
Troubleshooting
-If not connecting: check URL, CORS, transports.
-If events missing: verify room joins and event names.
-If duplicates: ensure deduplication in store.
-If auth failing: verify handshake token.
Checklist before adding new socket features
-Event added to shared constants.
-Server validates payload + permissions.
-Listeners cleaned up properly.
-UI updates idempotently.
-Test scenarios: offline, reconnect, multi-device.
Final notes
-
-Socket.IO is pre-included with Meetzy; run npm install to set everything up.
-Default flow covers real-time chat, media sharing, presence, and calls.
-Keep events centralized and versioned.
-Test reconnect and multi-tab behavior.
What's Next?
Start building fast, expressive real-time communication with Meetzy.