WebSocket على TypeScript: تقنيات متقدمة لتطبيقات الوقت الفعلي

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

WebSocket على TypeScript: تقنيات متقدمة لتطبيقات الوقت الفعلي



يوفر WebSocket اتصالاً ثنائي الاتجاه دائمًا بين العميل والخادم، مما يجعله مثاليًا لتطبيقات الوقت الفعلي: الدردشات، الإشعارات، التحرير المشترك والألعاب عبر الإنترنت. في هذه المقالة، سنستعرض تقنيات متقدمة للعمل مع WebSocket على TypeScript تتجاوز حدود خادم echo البسيط.



1. بنية إدارة الغرف (Rooms)



في التطبيقات الحقيقية، نادرًا ما يُستخدم البث العام لجميع العملاء. بل غالبًا ما يكون هناك حاجة لتقسيم العملاء منطقيًا إلى غرف (مثل غرف الدردشة أو جلسات الألعاب). دعنا نستعرض التنفيذ باستخدام TypeScript ومكتبة ws.



import { WebSocketServer, WebSocket } from 'ws';

interface Room { id: string; clients: Set<WebSocket>;}

class RoomManager { private rooms: Map<string, Room> = new Map();

createRoom(roomId: string): void { if (!this.rooms.has(roomId)) { this.rooms.set(roomId, { id: roomId, clients: new Set() }); } }

joinRoom(roomId: string, client: WebSocket): void { this.createRoom(roomId); this.rooms.get(roomId)!.clients.add(client); client.send(JSON.stringify({ type: 'room_joined', roomId })); }

leaveRoom(roomId: string, client: WebSocket): void { const room = this.rooms.get(roomId); if (room) { room.clients.delete(client); if (room.clients.size === 0) { this.rooms.delete(roomId); } } }

broadcastToRoom(roomId: string, message: object, sender?: WebSocket): void { const room = this.rooms.get(roomId); if (room) { const data = JSON.stringify(message); room.clients.forEach(client => { if (client.readyState === WebSocket.OPEN && client !== sender) { client.send(data); } }); } }}

const wss = new WebSocketServer({ port: 8080 });const roomManager = new RoomManager();

wss.on('connection', (ws: WebSocket) => { ws.on('message', (raw: Buffer) => { try { const msg = JSON.parse(raw.toString()); switch (msg.type) { case 'join': roomManager.joinRoom(msg.roomId, ws); break; case 'leave': roomManager.leaveRoom(msg.roomId, ws); break; case 'message': roomManager.broadcastToRoom(msg.roomId, { type: 'chat', user: msg.user, text: msg.text }, ws); break; } } catch (e) { ws.send(JSON.stringify({ type: 'error', message: 'Invalid JSON' })); } });

ws.on('close', () => { // التنظيف: إزالة العميل من جميع الغرف roomManager.leaveRoom('*', ws); });});


يوضح هذا الكود العمل الآمن مع الغرف: الإنشاء عند الطلب، التنظيف التلقائي للغرف الفارغة، واستثناء المرسل من البث.



2. المصادقة وإدارة الحالة



يجب مصادقة اتصالات WebSocket. النهج المتقدم هو التحقق من الرمز المميز (token) عند إنشاء الاتصال والحفاظ على الجلسة.



import { IncomingMessage } from 'http';import { WebSocketServer, WebSocket } from 'ws';

interface AuthenticatedSocket extends WebSocket { userId?: string; username?: string;}

const wss = new WebSocketServer({ port: 8080, verifyClient: (info: { req: IncomingMessage }, callback: (res: boolean) => void) => { const token = extractToken(info.req.url || ''); if (token && validateToken(token)) { callback(true); } else { callback(false); } }});

function extractToken(url: string): string | null { const params = new URLSearchParams(url.split('?')[1] || ''); return params.get('token');}

function validateToken(token: string): boolean { // يجب أن يكون هنا التحقق الفعلي من JWT أو أي رمز مميز آخر return token.length > 10;}

wss.on('co

المدونات

توصيات الكتب