Real-Time Communication Made Easy: Demonstrating Web Sockets with Angular

Web Sockets

Web sockets are a communication protocol that enables full-duplex, bidirectional communication between clients and servers over a single, long-lived connection. Unlike traditional HTTP requests, which are stateless and request-response based, web sockets allow real-time, event-driven communication. They are particularly useful for applications requiring instant updates, such as chat applications, collaborative tools, real-time dashboards, and more.

Web Sockets with Angular

Setting Up an Angular Project

To get started with web sockets in Angular, we need to set up a new project. Let's use the Angular CLI to scaffold the application structure and install any required dependencies. Open your terminal or command prompt and follow these steps:

Step 1. Install Angular CLI (if not already installed),

npm install -g @angular/cli

Step 2. Create a new Angular project.

ng new websocket-demo
cd websocket-demo

Establishing a Web Socket Connection

Now that we have our Angular project set up let's establish a web socket connection. We'll create a service that wraps the WebSocket API and handles the connection lifecycle. Open the terminal/command prompt and navigate to the project's root directory. Then, follow these steps.

1. Generate a WebSocket service.

ng generate service websocket

2. Open the newly generated service file (websocket.service.ts) and replace its content with the following code.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class WebsocketService {
  private socket: WebSocket;

  constructor() { }

  connect(): void {
    this.socket = new WebSocket('wss://your-websocket-url');

    this.socket.onopen = () => {
      console.log('WebSocket connection established.');
    };

    this.socket.onmessage = (event) => {
      console.log('Received message:', event.data);
    };

    this.socket.onclose = (event) => {
      console.log('WebSocket connection closed:', event);
    };

    this.socket.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
  }

  sendMessage(message: string): void {
    this.socket.send(message);
  }

  closeConnection(): void {
    this.socket.close();
  }
}

3. Replace 'wss://your-websocket-url' in the connect() the method with the actual WebSocket URL you want to connect to.

Sending and Receiving Data

With our web socket service in place, we can now send and receive data between the client and server. Open the component where you want to use the web socket service (e.g., app.component.ts) and follow these steps.

Import the WebSocket service

import { Component } from '@angular/core';
import { WebsocketService } from './websocket.service';

@Component({
  selector: 'app-root',
  template: `
    <button (click)="sendMessage()">Send Message</button>
  `
})
export class AppComponent {
  constructor(private websocketService: WebsocketService) {}

  sendMessage(): void {
    const message = 'Hello, WebSocket!';
    this.websocketService.sendMessage(message);
  }
}

In the same component file (e.g., app.component.ts), add the following code to receive messages from the server.

@Component({
  // Component configuration...
})
export class AppComponent implements OnInit {
  receivedMessages: string[] = [];

  constructor(private websocketService: WebsocketService) {}

  ngOnInit(): void {
    this.websocketService.connect();
    this.websocketService.messageReceived.subscribe((message: string) => {
      this.receivedMessages.push(message);
    });
  }

  sendMessage(): void {
    const message = 'Hello, WebSocket!';
    this.websocketService.sendMessage(message);
  }
}

In the component template (app.component.html), display the received messages.

<button (click)="sendMessage()">Send Message</button>

<ul>
  <li *ngFor="let message of receivedMessages">{{ message }}</li>
</ul>

Now, when the sendMessage() the method is called, it will send a message to the server using the web socket service. The received messages from the server are stored in the receivedMessages array and displayed in the component template.

Handling Errors and Disconnections

To handle errors and disconnections gracefully, let's make some modifications to our existing code. Open the websocket.service.ts file and follow these steps,

-  Import the Subject class from RxJS to handle the stream of received messages. Add the following line at the top of the file after the existing imports.

import { Subject } from 'rxjs';

-  Inside the WebsocketService class, declare a new messageReceived property of type Subject<string>. This will be used to emit and subscribe to the received messages:

messageReceived: Subject<string> = new Subject<string>();

-  In the onmessage event handler, modify the code to emit the received message through the messageReceived subject.

this.socket.onmessage = (event) => {
  const message = event.data;
  console.log('Received message:', message);
  this.messageReceived.next(message);
};

By implementing these changes, we are now using the messageReceived subject to emit and subscribe to the received messages in our Angular component. This allows us to handle and display the messages in real time.

Conclusion

In this article, we have explored how to implement web sockets in an Angular project to enable real-time communication between clients and servers. We covered the fundamentals of web sockets, including setting up an Angular project, establishing a web socket connection, sending and receiving data, and handling errors and disconnections.