WebSockets
وبسوکتها (WebSockets) در انگولار یکی از پیشرفتهترین روشها برای ایجاد ارتباط بلادرنگ (Real-Time) بین کلاینت و سرور هستند. بر خلاف درخواستهای HTTP که مبتنی بر مدل درخواست/پاسخ میباشند، وبسوکتها یک اتصال پایدار و دوطرفه برقرار میکنند که دادهها میتوانند بهصورت پیوسته و بدون نیاز به ارسال درخواست جدید رد و بدل شوند. این ویژگی در توسعه برنامههای تکصفحهای (SPA) که نیاز به بهروزرسانی لحظهای دارند — مانند چتها، اعلانها، دادههای زندهی مالی یا داشبوردهای پویا — بسیار حیاتی است.
در انگولار، پیادهسازی وبسوکتها معمولاً از طریق ترکیب سرویسها (Services)، کامپوننتها (Components) و مفاهیم واکنشی (Reactive Programming) با RxJS انجام میشود. بهکارگیری چرخهی حیات کامپوننتها (Lifecycle Hooks) باعث میشود تا اتصالها بهدرستی برقرار و هنگام تخریب کامپوننت آزاد شوند تا از نشت حافظه جلوگیری شود.
در این آموزش، یاد میگیرید چگونه وبسوکتها را در انگولار راهاندازی کنید، دادههای بلادرنگ را مدیریت کرده و وضعیت (State) را به شکل بهینه و واکنشی کنترل نمایید. این مفاهیم به شما کمک میکنند تا برنامههایی بسازید که سریع، واکنشگرا، مقیاسپذیر و مطابق با معماری مدرن کامپوننتمحور باشند.
مثال پایه
typescript// src/app/services/websocket.service.ts
import { Injectable, OnDestroy } from '@angular/core';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { Observable, Subscription } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class WebSocketService implements OnDestroy {
private socket$?: WebSocketSubject<any>;
private messages$?: Observable<any>;
private subscription?: Subscription;
connect(url: string): void {
if (!this.socket$ || this.socket$.closed) {
this.socket$ = webSocket(url);
this.messages$ = this.socket$.asObservable();
this.subscription = this.messages$.subscribe(
msg => console.log('پیام دریافتی:', msg),
err => console.error('خطا در اتصال:', err),
() => console.warn('اتصال بسته شد')
);
}
}
sendMessage(data: any): void {
this.socket$?.next(data);
}
close(): void {
this.socket$?.complete();
}
ngOnDestroy(): void {
this.subscription?.unsubscribe();
this.close();
}
}
// src/app/components/chat/chat.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { WebSocketService } from '../../services/websocket.service';
@Component({
selector: 'app-chat',
template: ` <div> <h3>چت بلادرنگ</h3> <input [(ngModel)]="message" placeholder="پیام خود را بنویسید..." /> <button (click)="send()">ارسال</button> </div>
`,
})
export class ChatComponent implements OnInit, OnDestroy {
message: string = '';
constructor(private wsService: WebSocketService) {}
ngOnInit(): void {
this.wsService.connect('wss://example.com/socket');
}
send(): void {
if (this.message.trim()) {
this.wsService.sendMessage({ text: this.message });
this.message = '';
}
}
ngOnDestroy(): void {
this.wsService.close();
}
}
کد بالا ساختار پایهی استفاده از وبسوکت در انگولار را نمایش میدهد. ابتدا در سرویس WebSocketService یک اتصال پایدار به سرور از طریق تابع connect() ایجاد شده است. این سرویس از RxJS و کلاس WebSocketSubject استفاده میکند تا ارتباطی واکنشی (Reactive) بین کلاینت و سرور برقرار کند.
مزیت استفاده از Observable در اینجا این است که هر پیام جدید بهصورت خودکار از طریق استریم دادهها به مشترکین ارسال میشود، و نیازی به درخواستهای مکرر وجود ندارد. با استفاده از ngOnDestroy()، اتصال و اشتراکها هنگام تخریب کامپوننت آزاد میشوند تا از نشت حافظه جلوگیری گردد.
در کامپوننت ChatComponent، کاربر میتواند پیام ارسال کند. هنگام بارگذاری (ngOnInit) اتصال باز میشود و هنگام خروج (ngOnDestroy) بسته میشود. این روش بهترین شیوهی مدیریت چرخهی حیات در انگولار است.
این مثال نشان میدهد که چگونه میتوان منطق وبسوکت را درون سرویسها محصور (encapsulate) کرد تا از تکرار کد جلوگیری شود و هر کامپوننت تنها وظیفهی نمایش و تعامل را بر عهده داشته باشد. چنین رویکردی باعث افزایش قابلیت تست، نگهداری و مقیاسپذیری پروژه میشود.
مثال کاربردی
typescript// src/app/components/stock-ticker/stock-ticker.component.ts
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
import { WebSocketService } from '../../services/websocket.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-stock-ticker',
template: ` <div> <h3>نمایش لحظهای قیمت سهام</h3> <ul> <li *ngFor="let stock of stocks">{{ stock.symbol }}: {{ stock.price | number:'1.2-2' }}</li> </ul> </div>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class StockTickerComponent implements OnInit, OnDestroy {
stocks: any[] = [];
private sub?: Subscription;
constructor(private wsService: WebSocketService) {}
ngOnInit(): void {
this.wsService.connect('wss://example.com/stocks');
this.sub = this.wsService['messages$']?.subscribe(
(data: any) => { this.stocks = data; },
err => console.error('خطای سوکت:', err)
);
}
ngOnDestroy(): void {
this.sub?.unsubscribe();
this.wsService.close();
}
}
در هنگام کار با وبسوکتها در انگولار، رعایت چند اصل کلیدی باعث افزایش کارایی و پایداری اپلیکیشن میشود.
اول، تمام منطق ارتباط وبسوکت باید در سرویسها نگهداری شود، نه درون کامپوننتها. این کار موجب جداسازی وظایف و جلوگیری از پیچیدگی غیرضروری میشود.
دوم، هنگام استفاده از استریمهای داده، همیشه اشتراکها را در ngOnDestroy آزاد کنید تا از Memory Leak جلوگیری شود.
از اشتباهات رایج در پروژههای انگولار میتوان به «تغییر مستقیم وضعیت (State Mutation)»، «بهروزرسانیهای غیرضروری (Unnecessary Re-renders)» و «انتقال زیاد داده بین کامپوننتها (Prop Drilling)» اشاره کرد. برای جلوگیری از این موارد میتوانید از استراتژی ChangeDetectionStrategy.OnPush و ساختارهای مدیریت حالت مانند NgRx استفاده کنید.
برای خطایابی، اپراتورهای RxJS مانند catchError و ابزارهای Angular DevTools کمک فراوانی میکنند. برای امنیت، همیشه از wss:// استفاده کرده و ورودیهای داده را اعتبارسنجی (sanitize) کنید تا از حملات XSS جلوگیری شود.
📊 جدول مرجع
| انگولار Element/Concept | Description | Usage Example |
|---|---|---|
| WebSocketService | سرویسی برای ایجاد و مدیریت اتصال وبسوکت | this.wsService.connect('wss://...') |
| RxJS webSocket | کلاس واکنشی برای مدیریت دادههای بلادرنگ | const socket = webSocket(url) |
| OnDestroy Lifecycle Hook | برای آزادسازی منابع هنگام تخریب کامپوننت | ngOnDestroy() { this.sub.unsubscribe(); } |
| ChangeDetectionStrategy.OnPush | جلوگیری از رندر غیرضروری | @Component({ changeDetection: OnPush }) |
| State Management | کنترل وضعیت دادهها بهصورت واکنشی | NgRx Store یا BehaviorSubject |
| catchError Operator | مدیریت خطا در استریم دادهها | messages$.pipe(catchError(...)) |
خلاصه و مراحل بعدی در انگولار:
در این آموزش با نحوهی کار وبسوکتها در انگولار آشنا شدید و یاد گرفتید چگونه با ترکیب RxJS، lifecycle hooks و معماری کامپوننتمحور، ارتباط بلادرنگ و امن ایجاد کنید.
این دانش به شما کمک میکند تا برنامههایی با قابلیت بهروزرسانی لحظهای مانند داشبوردهای داده، چت آنلاین و سیستمهای اطلاعرسانی توسعه دهید.
گام بعدی میتواند یادگیری ترکیب وبسوکتها با NgRx برای مدیریت وضعیت در پروژههای بزرگ باشد. همچنین یادگیری مفاهیمی مانند reconnect logic، message queuing و performance profiling باعث افزایش پایداری و بهینهسازی سیستم میشود.
همیشه در توسعهی پروژههای بلادرنگ، امنیت ارتباط، مدیریت چرخهی حیات و کاهش re-renderها را در اولویت قرار دهید تا تجربهی کاربری روان و حرفهایتری ارائه دهید.
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود