I followed this tutorial for establishing a websocket connection between python 3.8 Fast API Backend and Angular.
https://github.com/lynnkwong/websocket-fastapi-angular
Works fine so far, but what I want to achieve is that multiple clients get the changes made on the back end.
In the case provided, if you open the client from another browser, there will be a new websocket created so both frontends will not detect a change may by the other angular client, but only its own.
The question is is there a way to create such a websocket , that every front end connected client be able to detect changes made from the other clients?
I post the code from the tutorial here :
main.py in Python
import asyncio
import logging
from datetime import datetime
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("FastAPI app")
app = FastAPI()
async def heavy_data_processing(data: dict):
"""Some (fake) heavy data processing logic."""
await asyncio.sleep(2)
message_processed = data.get("message", "").upper()
return message_processed
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
# Accept the connection from a client.
await websocket.accept()
while True:
try:
# Receive the JSON data sent by a client.
data = await websocket.receive_json()
# Some (fake) heavey data processing logic.
message_processed = await heavy_data_processing(data)
# Send JSON data to the client.
await websocket.send_json(
{
"message": message_processed,
"time": datetime.now().strftime("%H:%M:%S"),
}
)
except WebSocketDisconnect:
logger.info("The connection is closed.")
break
Angular code :
App component.html :
<h2>Send a message to the server:</h2>
<form (ngSubmit)="sendMessage(message); message = ''">
<input [(ngModel)]="message" name="message" type="text" autocomplete="off" />
<button type="submit" style="margin-left: 10px;">Send</button>
</form>
<h2>Received messages from the server:</h2>
<ul>
<li *ngFor="let data of webSocketService.receivedData">
{{ data.time }}: {{ data.message }}
</li>
</ul>
app.component.ts :
import { Component, OnDestroy } from '@angular/core';
import { WebSocketService } from './websocket.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnDestroy {
message = '';
constructor(public webSocketService: WebSocketService) {
this.webSocketService.connect();
}
sendMessage(message: string) {
this.webSocketService.sendMessage(message);
}
ngOnDestroy() {
this.webSocketService.close();
}
}
websocket-service.ts :
import { Injectable } from '@angular/core';
import { webSocket, WebSocketSubject } from 'rxjs/webSocket';
import { environment } from '../environments/environment';
interface MessageData {
message: string;
time?: string;
}
@Injectable({
providedIn: 'root',
})
export class WebSocketService {
private socket$!: WebSocketSubject<any>;
public receivedData: MessageData[] = [];
public connect(): void {
if (!this.socket$ || this.socket$.closed) {
this.socket$ = webSocket(environment.webSocketUrl);
this.socket$.subscribe((data: MessageData) => {
this.receivedData.push(data);
});
}
}
sendMessage(message: string) {
this.socket$.next({ message });
}
close() {
this.socket$.complete();
}
}
2