1. Overview & Protocol
Nazexa Socket Platform operates a high-concurrency WebSocket engine powered by Node.js, Socket.IO v4, and Next.js. It allows applications to communicate bidirectionally with microsecond latency, exchange state across multi-tenant rooms, and execute remote events with guaranteed delivery.
Default Socket.IO multiplexing path with automatic WebSocket & HTTP long-polling fallback.
Initiates WebSocket upgrade immediately; supports HTTP polling for restricted corporate firewalls.
High-capacity message buffers with built-in per-IP rate-limiting and connection throttling.
2. Prerequisites & Credentials
Before connecting an external project (e.g. a Next.js frontend, React SPA, or Node backend), ensure you have created a Socket Server in your Nazexa Dashboard:
cly1234567890abcdef (cuid / UUID)
Unique identifier identifying your server cluster.
nsk_4f9a12c8e3b7...
32-byte cryptographic secret used for authenticating servers or issuing client tokens.
https://db.nazexa.com/ (or your production URL)
The host address running your Nazexa Socket Platform.
https://nazexa.com/, https://your-app.com
Configured under Server Settings to allow browser cross-origin handshakes.
npm install socket.io-client
3. Real-Time Architecture
Nazexa Socket Platform acts as a decoupled, standalone real-time hub. Client applications connect via WebSockets to listen for events and join dynamic rooms, while backend services can emit broadcasts over HTTP webhooks or direct sockets.
4. Authentication Modes
Every incoming handshake at /socket.io passes through Nazexa's strict socketAuthMiddleware. The platform offers two primary authentication strategies depending on whether the client is a public browser or a trusted backend worker:
Project Secret Key Auth
Ideal for background workers, microservices, seeders, or internal tools. The client passes projectId and secretKey in the handshake payload.
secretKey in public client-side code (such as client React components or Mobile app bundles).Client Auth Tokens (JWT)
Recommended for public web applications. Your backend issues a short-lived, signed JWT via the Nazexa REST API. The browser connects using only this temporary token with granular scopes.
Before your frontend connects, your backend server (e.g. Next.js, Express) calls this endpoint to mint a safe client token:
// app/api/socket-token/route.tsimport { NextResponse } from 'next/server';export async function GET() {// 1. Resolve your local user sessionconst currentUserId = "user_98765";const userEmail = "alex@acme.com";// 2. Mint short-lived client token from Nazexa Socket Platformconst res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/servers/${process.env.NAZEXA_PROJECT_ID}/client-token`,{method: 'POST',headers: {'Content-Type': 'application/json','x-secret-key': process.env.NAZEXA_SECRET_KEY!,},body: JSON.stringify({userId: currentUserId,username: userEmail,ttlHours: 4,}),});const data = await res.json();if (!res.ok) {return NextResponse.json({ error: 'Failed to mint token' }, { status: 500 });}return NextResponse.json({ token: data.token });}
5. Client & Backend Integrations
Connect your new project with modern Next.js 14 / 15 / 16 practices. Select your project framework below to inspect the exact configuration:
.env.local:# .env.local in your new projectNEXT_PUBLIC_APP_URL="https://ws.nazexa.com"NAZEXA_PROJECT_ID="your_project_id_from_dashboard"NAZEXA_SECRET_KEY="nsk_your_project_secret_key"
6. Custom useNazexaSocket Hook
Drop this enterprise-grade React hook directly into your new project at src/hooks/use-nazexa-socket.ts. It handles token resolution, connection lifecycle, automatic cleanup on unmount, and reconnect state:
'use client';import { useEffect, useState, useRef, useCallback } from 'react';import { io, Socket } from 'socket.io-client';export function useNazexaSocket({url = 'https://ws.nazexa.com',token,tokenEndpoint = '/api/socket-token',room,}: {url?: string;token?: string;tokenEndpoint?: string;room?: string;} = {}) {const [isConnected, setIsConnected] = useState(false);const [socketId, setSocketId] = useState<string | null>(null);const [error, setError] = useState<string | null>(null);const socketRef = useRef<Socket | null>(null);useEffect(() => {let isCancelled = false;let currentSocket: Socket | null = null;async function init() {try {let activeToken = token;if (!activeToken && tokenEndpoint) {const res = await fetch(tokenEndpoint);const data = await res.json();activeToken = data.token;}if (isCancelled) return;const socketInstance: Socket = io(url, {path: '/socket.io',auth: { token: activeToken },transports: ['websocket', 'polling'],});currentSocket = socketInstance;socketRef.current = socketInstance;socketInstance.on('connect', () => {if (!isCancelled) {setIsConnected(true);setSocketId(socketInstance.id || null);if (room) socketInstance.emit('room:join', room);}});socketInstance.on('disconnect', () => {if (!isCancelled) setIsConnected(false);});socketInstance.on('connect_error', (err) => {if (!isCancelled) setError(err.message);});} catch (err: any) {if (!isCancelled) setError(err.message);}}void init();return () => {isCancelled = true;currentSocket?.disconnect();};}, [url, token, tokenEndpoint, room]);const emitEvent = useCallback((event: string, data: unknown, targetRoom?: string) => {socketRef.current?.emit('event:emit', {event,room: targetRoom || room,data,});}, [room]);return { socket: socketRef.current, isConnected, socketId, error, emitEvent };}
7. Multi-Tenant Rooms
Nazexa Socket Platform isolates event streams using logical rooms. When a socket joins a room, the platform tracks active occupant counters and fires live telemetry to your admin dashboard.
Joins the specified channel. Automatically updates active room counters in the database.
Unsubscribes from events. If member count reaches 0, the room is marked inactive.
user:<externalId>: Each authenticated socket automatically joins its personal user room for direct user-to-user notifications.server:<serverId>: Auto-joined room for server-wide broadcasts affecting all clients connected to this instance.
8. Bidirectional Events
Clients emit messages using the unified event:emit event. The Nazexa gateway verifies rate limits, checks for the socket:write scope, logs the event size for telemetry, and forwards it to the target room:
// 1. Define your payload interfaceinterface DocumentPayload {documentId: string;savedBy: string;updatedAt: string;}// 2. Publishing an event to a room from clientsocket.emit('event:emit', {room: 'project:abc1234',event: 'document:saved',data: {documentId: 'doc_55',savedBy: 'alex',updatedAt: new Date().toISOString(),} satisfies DocumentPayload,});// 3. Listening for that event with strict typingsocket.on('document:saved', (payload: DocumentPayload) => {console.log('Document updated by peer:', payload.savedBy);});
9. Backend Webhook Emitter
If your background jobs run on serverless functions (e.g. Vercel, AWS Lambda) where persistent WebSockets are not ideal, you can emit events to connected users via a simple HTTP POST request to /internal/emit:
// lib/nazexa-emitter.tsexport async function emitServerEvent(room: string, event: string, data: unknown) {const res = await fetch('https://ws.nazexa.com/internal/emit', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({projectId: process.env.NAZEXA_PROJECT_ID,secretKey: process.env.NAZEXA_SECRET_KEY,room,event,data,}),});if (!res.ok) {throw new Error('Failed to emit real-time event');}}
10. Troubleshooting & FAQ
Go to your server's Settings in the Nazexa Dashboard and verify that allowedOrigins contains your frontend domain (e.g. https://nazexa.com/ or *).
The client must supply either auth: { token: '...' } or auth: { projectId, secretKey } in the initial handshake. Verify that the secret key hasn't been regenerated.
Individual sockets are subject to per-minute event ceilings to protect server health. Adjust rateLimitPerMinute in your server settings if higher throughput is required.
