Real-time Chat Example
A complete working real-time chat application with WebSockets. Copy, run, and customize.
Complete Working Example
1// src/server.ts - Basic Implementation
2import { createApp, z, validate, SocketIOAdapter } from '@morojs/moro';
3
4// Create app with WebSocket support
5const app = createApp({
6 server: { port: 3000, host: '0.0.0.0' },
7 websocket: { enabled: true, adapter: new SocketIOAdapter() },
8});
9
10// Simple in-memory storage for demo
11const users: any[] = [];
12const rooms: any[] = [
13 { id: 'general', name: 'General Chat', description: 'Main chat room' },
14 { id: 'random', name: 'Random', description: 'Random discussions' }
15];
16const messages: any[] = [];
17
18// Basic welcome endpoint
19app.get('/', (req, res) => {
20 return {
21 message: 'Real-time Chat API - Simple Demo',
22 status: 'running',
23 version: '1.0.0',
24 note: 'This is a simplified demo without database dependencies',
25 endpoints: [
26 'GET / - This message',
27 'GET /health - Health check',
28 'GET /rooms - Get available rooms',
29 'GET /test - WebSocket test client (open in browser)',
30 'POST /auth/register - Simple user registration (no persistence)',
31 'POST /auth/login - Simple user login (no persistence)',
32 'WebSocket /chat - Real-time chat functionality'
33 ],
34 websocket: {
35 url: 'ws://localhost:3000/chat',
36 events: ['join', 'message', 'leave']
37 }
38 };
39});
40
41// Simple authentication endpoints (no database)
42app.post('/auth/register',
43 validate({
44 body: z.object({
45 username: z.string().min(3).max(20),
46 email: z.string().email(),
47 password: z.string().min(6)
48 })
49 }, async (req, res) => {
50 // Check if user already exists
51 const existingUser = users.find(u => u.email === req.body.email || u.username === req.body.username);
52 if (existingUser) {
53 res.status(400);
54 return { error: 'User already exists with this email or username' };
55 }
56
57 // Create user (in memory)
58 const user = {
59 id: Date.now().toString(),
60 username: req.body.username,
61 email: req.body.email,
62 createdAt: new Date().toISOString()
63 };
64
65 users.push(user);
66
67 return {
68 user,
69 token: `demo-token-${user.id}`,
70 message: 'User registered successfully (demo mode - no persistence)'
71 };
72 })
73);
74
75// Basic WebSocket handler
76app.websocket('/chat', {
77 connect: (socket: any) => {
78 console.log(`🔗 WebSocket client connected: ${socket.id}`);
79 },
80
81 disconnect: (socket: any) => {
82 console.log(`❌ WebSocket client disconnected: ${socket.id}`);
83 },
84
85 join: (socket: any, data: any) => {
86 console.log(`📝 Join event received:`, data);
87 const roomId = data.roomId || 'general';
88 const username = data.username || 'Anonymous';
89
90 console.log(`👥 ${username} joined room ${roomId}`);
91
92 return {
93 success: true,
94 message: `Joined room ${roomId}`,
95 room: rooms.find(r => r.id === roomId) || { id: roomId, name: roomId }
96 };
97 },
98
99 message: (socket: any, data: any) => {
100 console.log(`💬 Message event received:`, data);
101 const roomId = data.roomId || 'general';
102 const username = data.username || 'Anonymous';
103
104 const message = {
105 id: Date.now(),
106 content: data.message,
107 sender: username,
108 roomId,
109 timestamp: new Date().toISOString()
110 };
111
112 // Store message in memory
113 messages.push(message);
114 console.log(`📨 Broadcasting message to room ${roomId}:`, message);
115
116 return { success: true, message: 'Message sent' };
117 }
118});
119
120// REST API endpoints
121app.get('/rooms', (req, res) => {
122 return {
123 rooms,
124 message: 'Available chat rooms'
125 };
126});
127
128app.get('/rooms/:roomId/messages', (req, res) => {
129 const roomMessages = messages
130 .filter(m => m.roomId === req.params.roomId)
131 .slice(-50); // Last 50 messages
132
133 return {
134 messages: roomMessages,
135 roomId: req.params.roomId,
136 count: roomMessages.length
137 };
138});
139
140app.listen(() => {
141 const config = app.getConfig();
142 console.log(`Real-time Chat Server running on port ${config.server.port}`);
143 console.log(`WebSocket endpoint: ws://localhost:${config.server.port}/chat`);
144 console.log(`Test client: http://localhost:${config.server.port}/test`);
145});What This Does
- Creates a real-time chat server with WebSocket support
- Handles user registration and authentication (in-memory demo)
- Manages chat rooms and real-time messaging
- Provides REST API endpoints for rooms and message history
Key Features Highlighted
WebSocket Event Handling
1// Basic WebSocket handler
2app.websocket('/chat', {
3 connect: (socket: any) => {
4 console.log(`🔗 WebSocket client connected: ${socket.id}`);
5 },
6
7 disconnect: (socket: any) => {
8 console.log(`❌ WebSocket client disconnected: ${socket.id}`);
9 },
10
11 join: (socket: any, data: any) => {
12 const roomId = data.roomId || 'general';
13 const username = data.username || 'Anonymous';
14 return {
15 success: true,
16 message: `Joined room ${roomId}`
17 };
18 },
19
20 message: (socket: any, data: any) => {
21 const message = {
22 id: Date.now(),
23 content: data.message,
24 sender: data.username,
25 roomId: data.roomId,
26 timestamp: new Date().toISOString()
27 };
28 return { success: true, message: 'Message sent' };
29 }
30});Try It Yourself
Copy the code above, save it as server.ts, and run:
1# Install dependencies
2npm install @morojs/moro socket.io
3
4# Run the server
5npx tsx server.tsAvailable Endpoints
GET http://localhost:3000/
GET http://localhost:3000/rooms
POST http://localhost:3000/auth/register
WebSocket ws://localhost:3000/chat
Getting Started
Setup and Run
bash
1# Clone and setup
2git clone https://github.com/Moro-JS/examples.git
3cd examples/real-time-chat
4
5# Install dependencies
6npm install
7
8# Start development server (no database setup required)
9npm run dev
10
11# Access the application:
12# - API: http://localhost:3000
13# - WebSocket Test Client: http://localhost:3000/test
14# - WebSocket: ws://localhost:3000/chat
15
16# Available endpoints:
17# GET / - API documentation
18# GET /rooms - Available chat rooms
19# POST /auth/register - User registration (in-memory)
20# POST /auth/login - User login (in-memory)
21# GET /rooms/:roomId/messages - Get room messages
22
23# Available commands:
24npm run dev # Start development server
25npm run build # Build for production
26npm run start # Start production server
27
28# Note: This is a simplified demo with in-memory storage
29# No database setup required for basic functionalityWhat You'll Learn
- •WebSocket connection management
- •Real-time event broadcasting
- •Message persistence strategies
- •User presence tracking
- •Scaling real-time applications
- •Client-server synchronization