UNPKG

onilib

Version:

A modular Node.js library for real-time online integration in games and web applications

336 lines (281 loc) โ€ข 9.18 kB
// Exemplo bรกsico de uso da ONILib const { NodeOnlineIntegration } = require('../src/index.js'); // Configuration for the example server const config = { name: 'basic-game-server', environment: 'development', // Server ports port: 3000, host: '0.0.0.0', // Authentication auth: { jwtSecret: 'example-secret-key', jwtExpiresIn: '24h', apiKeys: ['demo_api_key_123'] }, // WebSocket/Realtime realtime: { port: 8080, maxConnections: 100, heartbeatInterval: 30000, authRequired: true }, // Storage (using SQLite for this example) storage: { type: 'sqlite', path: './data/example.db' }, // Matchmaking matchmaking: { maxPlayersPerMatch: 2, matchTimeout: 30000, queueTimeout: 300000, enableSkillMatching: true }, // P2P/WebRTC p2p: { enableRelay: false, maxPeersPerRoom: 4, iceServers: [ { urls: 'stun:stun.l.google.com:19302' } ] }, // Admin panel admin: { port: 3001, authRequired: true, enableCors: true } }; async function startServer() { console.log('๐Ÿš€ Iniciando servidor ONILib...'); // Create NOI instance const noi = new NodeOnlineIntegration(config); try { // Start the server await noi.start(); // Get module references const realtime = noi.getModule('realtime'); const matchmaking = noi.getModule('matchmaking'); const storage = noi.getModule('storage'); const p2p = noi.getModule('p2p'); const auth = noi.getModule('auth'); console.log('โœ… Servidor ONILib iniciado com sucesso!'); console.log(`๐Ÿ“ก WebSocket server: ws://localhost:${config.realtime.port}`); console.log(`๐ŸŒ Admin panel: http://localhost:${config.admin.port}`); console.log(`๐Ÿ”‘ Demo API Key: ${config.auth.apiKeys[0]}`); // Setup custom message handlers setupMessageHandlers(realtime, matchmaking, storage, p2p); // Setup matchmaking events setupMatchmakingEvents(matchmaking, realtime, storage); // Setup P2P events setupP2PEvents(p2p, realtime); // Create some demo data await createDemoData(storage, auth); console.log('\n๐Ÿ“‹ Available features:'); console.log(' โ€ข Authentication (JWT & API Key)'); console.log(' โ€ข Real-time messaging with rooms'); console.log(' โ€ข Matchmaking with skill-based matching'); console.log(' โ€ข P2P WebRTC signaling'); console.log(' โ€ข Persistent storage (SQLite)'); console.log(' โ€ข Admin REST API'); console.log('\n๐ŸŽฎ Try the example client:'); console.log(' Open examples/client.html in your browser'); } catch (error) { console.error('โŒ Erro ao iniciar servidor ONILib:', error); process.exit(1); } } function setupMessageHandlers(realtime, matchmaking, storage, p2p) { // Custom game message handler realtime.registerHandler('game_action', async (client, message) => { console.log(`๐ŸŽฎ Game action from ${client.id}:`, message.data); // Store the action in database await storage.set(`action:${client.id}:${Date.now()}`, { playerId: client.id, action: message.data.action, timestamp: Date.now(), roomId: client.currentRoom }); // Broadcast to room members if (client.currentRoom) { realtime.broadcastToRoom(client.currentRoom, { type: 'game_action_broadcast', data: { playerId: client.id, action: message.data.action, timestamp: Date.now() } }, client.id); // Exclude sender } }); // Player status update realtime.registerHandler('player_status', async (client, message) => { const status = message.data.status; // Update player status in storage await storage.set(`player:${client.id}:status`, { status, lastUpdate: Date.now() }); // Notify room members if (client.currentRoom) { realtime.broadcastToRoom(client.currentRoom, { type: 'player_status_update', data: { playerId: client.id, status, timestamp: Date.now() } }, client.id); } console.log(`๐Ÿ‘ค Player ${client.id} status: ${status}`); }); // Chat message handler realtime.registerHandler('chat_message', async (client, message) => { const chatMessage = { id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, playerId: client.id, text: message.data.text, timestamp: Date.now(), roomId: client.currentRoom }; // Store chat message await storage.set(`chat:${chatMessage.id}`, chatMessage); // Broadcast to room if (client.currentRoom) { realtime.broadcastToRoom(client.currentRoom, { type: 'chat_message_broadcast', data: chatMessage }); } console.log(`๐Ÿ’ฌ Chat from ${client.id}: ${message.data.text}`); }); } function setupMatchmakingEvents(matchmaking, realtime, storage) { // When a match is created matchmaking.on('match:created', async (match) => { console.log(`๐ŸŽฏ Match created: ${match.id} with ${match.players.length} players`); // Store match data await storage.set(`match:${match.id}`, { id: match.id, players: match.players.map(p => ({ id: p.id, skill: p.skill })), status: 'created', createdAt: Date.now() }); }); // When a match starts matchmaking.on('match:started', async (match) => { console.log(`๐Ÿš€ Match started: ${match.id}`); // Update match status const matchData = await storage.get(`match:${match.id}`); if (matchData) { matchData.status = 'started'; matchData.startedAt = Date.now(); await storage.set(`match:${match.id}`, matchData); } // Create a dedicated room for the match const roomId = `match_${match.id}`; // Send game start notification to all players for (const player of match.players) { realtime.sendToClient(player.client, { type: 'match_started', data: { matchId: match.id, roomId, players: match.players.map(p => ({ id: p.id, skill: p.skill })), gameMode: 'default' } }); // Auto-join players to match room realtime.joinRoom(player.client, roomId); } }); // When a match ends matchmaking.on('match:ended', async (match) => { console.log(`๐Ÿ Match ended: ${match.id}`); // Update match status const matchData = await storage.get(`match:${match.id}`); if (matchData) { matchData.status = 'ended'; matchData.endedAt = Date.now(); await storage.set(`match:${match.id}`, matchData); } }); } function setupP2PEvents(p2p, realtime) { // When a peer joins a P2P room p2p.on('peer:joined_room', ({ peer, roomId }) => { console.log(`๐Ÿ”— Peer ${peer.id} joined P2P room: ${roomId}`); // Notify other peers in the room const room = p2p.rooms.get(roomId); if (room) { for (const otherPeer of room.peers.values()) { if (otherPeer.id !== peer.id) { realtime.sendToClient(otherPeer.client, { type: 'p2p_peer_joined', data: { peerId: peer.id, roomId } }); } } } }); // When a peer leaves a P2P room p2p.on('peer:left_room', ({ peer, roomId }) => { console.log(`๐Ÿšช Peer ${peer.id} left P2P room: ${roomId}`); // Notify remaining peers const room = p2p.rooms.get(roomId); if (room) { for (const otherPeer of room.peers.values()) { realtime.sendToClient(otherPeer.client, { type: 'p2p_peer_left', data: { peerId: peer.id, roomId } }); } } }); } async function createDemoData(storage, auth) { console.log('๐Ÿ“Š Creating demo data...'); // Create demo users const demoUsers = [ { id: 'user1', username: 'Alice', skill: 1200 }, { id: 'user2', username: 'Bob', skill: 1150 }, { id: 'user3', username: 'Charlie', skill: 1300 } ]; for (const user of demoUsers) { await storage.set(`user:${user.id}`, user); // Create JWT token for demo user const token = auth.generateJWT({ userId: user.id, username: user.username }); console.log(`๐Ÿ”‘ Demo JWT for ${user.username}: ${token}`); } // Create demo game rooms const demoRooms = [ { id: 'lobby', name: 'Main Lobby', maxPlayers: 50 }, { id: 'casual', name: 'Casual Games', maxPlayers: 10 }, { id: 'ranked', name: 'Ranked Matches', maxPlayers: 8 } ]; for (const room of demoRooms) { await storage.set(`room:${room.id}`, room); } console.log('โœ… Demo data created'); } // Graceful shutdown process.on('SIGINT', async () => { console.log('\n๐Ÿ›‘ Shutting down server...'); process.exit(0); }); process.on('SIGTERM', async () => { console.log('\n๐Ÿ›‘ Shutting down server...'); process.exit(0); }); // Start the server if (require.main === module) { startServer().catch(console.error); } module.exports = { startServer, config };