EN

Search
Close this search box.

موستانگ، وحشیِ دوست داشتنی

پاسخ داده شد
0
0

چطور websocket را پیاده سازی کنیم؟ مثلاً می خواهیم یک سیستم چتینگ داشته باشیم که بصورت real time پیام ها را ارسال کند و آنلاین بودن کاربران را نشان دهد

  • شما باید برای ارسال دیدگاه شوید
پاسخ عالی
0
0

فرض کنید یک اپلیکیشن چت نوشتیم و می خواهیم بصورت real time پیام ها را نمایش دهیم. یعنی وقتی کاربر1 به کاربر2  پیام می فرستد، نیازی به رفرش کردن صفحه نباشد. یا مثلاً وقتی کاربر1 وارد صفحه چت شد، آنلاین بودنش به تمامی دوستانش نمایش داده شود. برای این طور کارها از مفهومی بنام websocket استفاده می کنیم.

websocket نوعی از کانکشن است. برعکس کانکشن http که بعد از ارسال داده بسته می شود، websocket کانکشنی است که تا زمانیکه دو طرف بخواهند باز می ماند و می توان بینشان داده رد و بدل کرد. کانکشن websocket به جای http با ws شروع می شود.

حالا چطور از websocket استفاده کنیم؟

websocket را باید برای server و client جدا پیاده سازی کنیم.

اول لازم است تا روی سرور یک gateway باز کنیم. gateway سروری است که روی یک پورت بالا می آید و همیشه بالا است. client ها با websocket به آن connect و disconnect می شوند، message ارسال می کنند و به تمامی message هایی که ارسال می شود گوش می دهند. (gateway  هم می تواند به تمامی client هایی که وصل هستند، یک message را ارسال کند)

مثلاً وقتی کاربر1 وارد چت می شود، با یک websocket به gateway وصل می شود. حالا ما می توانیم به تمامی کاربرانی که داخل آن چت روم هستند آنلاین شدن کاربر1 را اطلاع دهیم. یا اگر کاربر1 پیامی به کاربر2 ارسال کند، پیام را بلافاصله به کاربر2 ارسال کنیم. (چون کاربر2 هم به gateway متصل است)

برای مثال، ما اینجا در سمت client از react استفاده می کنیم و در سمت سرور از nest.js

 

سمت سرور

یک پروژه nest.js بسازید. بهتر است پروژه websocket را از پروژه اصلی back-end تان جدا کنید. (تا به تداخل depency ها برنخورید. می توانید هر کدام را هم روی یک پورت جدا بالا بیاورید)

کتابخانه های زیر را نصب کنید:

npm install socket.io @nestjs/websockets

داخل فولدر src پروژه یک فولدر بنام websocket بسازید و دو فایل با نامهای websocket.module.ts و websocket.service.ts بسازید.

فایل یک ماژول است که باید فایل را به عنوان provider برایش تعریف کنید:

// websocket.module.ts
import { Module } from '@nestjs/common';
import { WebSocketService } from './websocket.service'; // Import your WebSocket gateway


@Module({
  providers: [WebSocketService], // Add your WebSocket gateway here
})
export class WebSocketModule {}

باید داخل فایل app.module.ts هم ماژولی که ساختید را ایمپورت کنید:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { WebSocketModule } from './websocket/websocket.module';

@Module({
  imports: [WebSocketModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

فایل websocket.service.ts ، فایل اصلی است که وطیفه اش ساختن gateway است:

import { ConnectedSocket, MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer } from '@nestjs/websockets';
import { Server } from 'socket.io';
import { Socket } from 'socket.io';
import { Logger } from '@nestjs/common';


@WebSocketGateway()
export class WebSocketService implements OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer()
  server: Server;
  private readonly logger = new Logger(WebSocketService.name);


  constructor() {
    console.log('WebSocketService initialized'); 
  }



  
  afterInit(server: Server) {
    console.log('Initialized');
  }

  

  handleConnection(client: Socket) {
    console.log(`Client connected: ${client.id}`);
    // Handle connection event
  }
  
  handleDisconnect(client: Socket) {
    console.log(`Client disconnected: ${client.id}`);
    // Handle disconnection event
  }
  
  @SubscribeMessage('chat_message')
  handleMessage(@MessageBody() data: string, @ConnectedSocket() client: Socket) {
    console.log(`Received message from ${client.id}: ${data}`);
    // Handle received message
    this.server.emit('chat_message', data); // Broadcast the message to all connected clients
  }



  @SubscribeMessage('joinChatRoom')
  handlejoinChatRoom(@MessageBody() data: string, @ConnectedSocket() client: Socket) {
    console.log(`joinChatRoom with id : ${data}`);

    this.server.emit('joinChatRoom', data);
  }

  @SubscribeMessage('leftChatRoom')
  handleLeftChatRoom(@MessageBody() data: string, @ConnectedSocket() client: Socket) {

    this.server.emit('leftChatRoom', data); 
  }


  
  
@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}


  
}

*SubscribeMessage('joinChatRoom') مشخص می کند پیامی که ارسال و دریافت می شود با چه آیدی است (joinChatRoom) . در سمت فرانت هم باید با همین آیدی پیامتان را ارسال و دریافت کنید.

* this.server.emit('leftChatRoom', data); پیام را به تمامی client هایی که به این gateway هستند ارسال می کند.

سمت client

سمت فرانت ، مثلا جایی که کاربر صفحه چت را باز می کند، یک useEffect بنویسید که اتصال websocket را برقرار کند و به event ها (یا همان پیامها) که می آید گوش دهد. با تابع emit هم می توانید به gateway داده ارسال کنید:

*یادتان باشد که وقتی صفحه چت بسته شد، حتما socket را ببندید.

useEffect( () => {
      
      const initializeSocket = async () =>
      {
        
        
        const socket = io('ws://localhost:5000', { transports: ['websocket'] });


        socket.on('chat_message', async (chat_message) => {

          console.log("chat_message",chat_message);
      
        });

      
        socket.on('joinChatRoom', async (joinChatRoom) => {

          console.log("socket joinChatRoom",joinChatRoom);
        });

        socket.on('leftChatRoom', async (leftChatRoom) => {
    
          console.log("socket leftChatRoom",leftChatRoom);
        });


        socket.on('connect', () => {
          console.log('Connected to WebSocket');
        });
        
        socket.on('disconnect', () => {
          console.log('Disconnected from WebSocket');
          
        });


    
      }

      
      return () => {

        socket?.emit("leftChatRoom",{user_id:onlineUser._id})
        socket?.disconnect(); // Disconnect when the component unmounts
      };

      
    }, [messageDialog]);

* ws://localhost:5000آدرس پورت سرور است که gateway را روی آن بالا آوردید. اگر از https استفاده می کنید به جای ws از wss استفاده کنید.

*هر جایی از برنامه ، مثلا وقتی کاربر پیامی جدید ارسال کرد، می توانید به gateway هم ارسال کنید:

socket.emit('chat_message', data );
  • شما باید برای ارسال دیدگاه شوید
نمایش 1 نتیجه
پاسخ شما
اگر قبلاً حساب کاربری دارید با پر کردن فیلد های زیر یا به عنوان مهمان ارسال کنید.
نام*
ایمیل*
وب سایت