<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged web-socket</title>
<link>https://coderlegion.com/tag/web-socket</link>
<description>Powered by Question2Answer</description>
<item>
<title>GroqStreamChain: Revolutionizing Real-Time AI Chat with WebSocket and Groq</title>
<link>https://coderlegion.com/4137/groqstreamchain-revolutionizing-real-time-ai-chat-with-websocket-and-groq</link>
<description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the world of AI-powered chat applications, real-time communication and quick response times are crucial. GroqStreamChain is a project that combines cutting-edge technologies to create a seamless, low-latency chat system. This project leverages WebSocket for instant communication and streams AI responses powered by Groq and LangChain, providing an immersive user experience with real-time feedback.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is GroqStreamChain?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GroqStreamChain is a real-time chat system designed to facilitate smooth interactions between users and AI. By using WebSocket, this system ensures that the chat messages are delivered instantly, with minimal delay. The chat application streams responses chunk by chunk, which not only reduces latency but also enhances the user experience by providing quick feedback. At its core, GroqStreamChain integrates Groq's powerful LLMs (large language models) and LangChain, an integration tool that connects various language models to applications, ensuring smart and dynamic responses.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Features of GroqStreamChain&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Real-Time Communication via WebSocket&lt;/strong&gt;&lt;br&gt;
The system is built around WebSocket, allowing instant and low-latency communication. This helps in reducing any delays in message delivery, which is crucial for an interactive chat experience.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streaming Responses&lt;/strong&gt;&lt;br&gt;
Instead of waiting for the full response from the language model, GroqStreamChain streams responses as they are generated. This feature makes the system feel faster by showing partial responses to the user immediately.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Efficient Session Management&lt;/strong&gt;&lt;br&gt;
Every user gets a unique chat session automatically, ensuring that interactions are personalized and persistent across sessions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User-Friendly Frontend&lt;/strong&gt;&lt;br&gt;
The chat application offers a clean, responsive UI that includes typing indicators and message formatting, making the chat experience visually appealing and smooth.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Robust Error Handling&lt;/strong&gt;&lt;br&gt;
WebSocket disconnections and reconnections are managed with care, ensuring the system continues to function seamlessly even in case of network issues.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Project Structure&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GroqStreamChain follows a modular approach, organizing the project into distinct files and folders for efficient management and easy navigation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;server.py&lt;/code&gt;&lt;/strong&gt;: The core FastAPI server responsible for managing WebSocket connections.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;config.py&lt;/code&gt;&lt;/strong&gt;: This file handles configuration settings like API keys and model configurations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;models/chat.py&lt;/code&gt;&lt;/strong&gt;: Contains the data models used to handle chat messages and sessions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;services/llm_service.py&lt;/code&gt;&lt;/strong&gt;: Connects with Groq and LangChain to generate AI-powered responses.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frontend&lt;/strong&gt;: Contains the HTML, CSS, and JavaScript files that make up the user interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;How to Get Started&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Setting up GroqStreamChain on your local machine is simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clone the repository&lt;/strong&gt;:&lt;br&gt;
Begin by cloning the repository to your local machine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install dependencies&lt;/strong&gt;:&lt;br&gt;
You can install the necessary libraries using &lt;code&gt;pip&lt;/code&gt; or &lt;code&gt;conda&lt;/code&gt;. It's recommended to create a separate Conda environment for the project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set up environment variables&lt;/strong&gt;:&lt;br&gt;
In your project directory, create a &lt;code&gt;.env&lt;/code&gt; file and add your Groq API key and the model name to connect to the Groq service.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run the server&lt;/strong&gt;:&lt;br&gt;
Once you've set everything up, start the server with a simple command and access the chat application through your browser.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Testing the Groq API&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The repository also includes a test script to verify that the Groq API is set up correctly. This is useful for ensuring that the connection to the Groq model is working as expected. Running the test script will allow you to see if you receive the expected responses from Groq.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Performance Considerations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GroqStreamChain is designed to handle communication and AI processing efficiently:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Persistent WebSocket connection&lt;/strong&gt;: By maintaining an open connection, the system ensures fast communication without the overhead of reconnecting.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Real-time response streaming&lt;/strong&gt;: The system minimizes latency by delivering partial responses while the full response is still being generated.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimized server-side processing&lt;/strong&gt;: The backend server offloads heavy tasks to Groq's powerful model, ensuring minimal processing on the server side and faster responses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GroqStreamChain brings real-time AI chat capabilities to a new level by using WebSocket for seamless communication and integrating powerful AI responses powered by Groq. Whether you're building customer support bots or AI-driven personal assistants, GroqStreamChain provides the tools needed to create an efficient and responsive chat system. Check out the repository, set it up locally, and explore how this cutting-edge technology can help enhance user interaction in real-time.&lt;/p&gt;
&lt;p&gt;For a more detailed walkthrough, feel free to explore the full documentation in the GitHub repository.&lt;/p&gt;
&lt;p&gt;Repository link: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/pr0mila/GroqStreamChain&quot;&gt;https://github.com/pr0mila/GroqStreamChain&lt;/a&gt;&lt;/p&gt;
</description>
<category>Deep Learning</category>
<guid isPermaLink="true">https://coderlegion.com/4137/groqstreamchain-revolutionizing-real-time-ai-chat-with-websocket-and-groq</guid>
<pubDate>Fri, 18 Jul 2025 12:38:54 +0000</pubDate>
</item>
<item>
<title>How to Add Functional Stock Updates: Achieve a Production-Ready and Scalable Solution</title>
<link>https://coderlegion.com/3336/how-to-add-functional-stock-updates-achieve-a-production-ready-and-scalable-solution</link>
<description>&lt;p&gt;To build a &lt;strong&gt;production-ready, scalable stock update system&lt;/strong&gt; with &lt;strong&gt;real-time updates in Angular&lt;/strong&gt;, you’ll want to combine a solid &lt;strong&gt;frontend WebSocket setup&lt;/strong&gt; with a robust &lt;strong&gt;backend&lt;/strong&gt; (like Node.js + Redis + Kafka or a managed service). &lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;real-time-stock-updates-in-angular&quot;&gt;Real-Time Stock Updates in Angular&lt;/h3&gt;
&lt;h4 id=&quot;features-&quot;&gt;Features:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Live stock prices pushed to frontend&lt;/li&gt;
&lt;li&gt;Scalable (1000s of clients)&lt;/li&gt;
&lt;li&gt;Low latency&lt;/li&gt;
&lt;li&gt;Production-ready (auth, error handling, reconnection, observables)&lt;/li&gt;
&lt;li&gt;Efficient resource use (pub/sub pattern)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;architecture&quot;&gt;Architecture&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;  +---------------------+
  | External Stock API  | &amp;lt;---- Polls every few seconds or via Webhook
  +---------------------+
            |
            v
  +---------------------+
  |    Node.js Server   |  &amp;lt;---- Aggregator, pushes data
  | with Redis Pub/Sub  |
  +---------------------+
            |
     WebSocket (Socket.IO)
            |
    +---------------+
    | Angular Client|
    +---------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;tech-stack&quot;&gt;Tech Stack&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Component          &lt;/th&gt;&lt;th&gt;Tool                              &lt;/th&gt;&lt;th&gt;Notes&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Frontend           &lt;/td&gt;&lt;td&gt;Angular + Socket.IO-client        &lt;/td&gt;&lt;td&gt;For real-time updates&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Backend            &lt;/td&gt;&lt;td&gt;Node.js + Socket.IO               &lt;/td&gt;&lt;td&gt;Real-time server&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Cache / Pub-Sub    &lt;/td&gt;&lt;td&gt;Redis                             &lt;/td&gt;&lt;td&gt;Push latest stock data to all instances&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Optional           &lt;/td&gt;&lt;td&gt;Kafka / RabbitMQ                  &lt;/td&gt;&lt;td&gt;For heavy loads / message queues&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;External Stock API &lt;/td&gt;&lt;td&gt;Alpha Vantage, IEX Cloud, Finnhub &lt;/td&gt;&lt;td&gt;For stock data&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id=&quot;backend-node-js-redis-socket-io-&quot;&gt;Backend (Node.js + Redis + Socket.IO)&lt;/h3&gt;
&lt;h4 id=&quot;1-install-dependencies&quot;&gt;1. Install dependencies&lt;/h4&gt;
&lt;p&gt;npm install express socket.io redis axios&lt;/p&gt;
&lt;h4 id=&quot;2-backend-code-server-js-&quot;&gt;2. Backend Code (&lt;code&gt;server.js&lt;/code&gt;)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const axios = require('axios');
const redis = require('redis');

const app = express();
const server = http.createServer(app);
const io = new Server(server, {
  cors: { origin: '*' }
});

const redisClient = redis.createClient();
redisClient.connect();

// Poll stock price every 5 seconds
async function fetchAndBroadcastStock() {
  try {
    const response = await axios.get('https://api.example.com/stock/GOOG');
    const stockPrice = response.data.price;

    // Store in Redis
    await redisClient.set('stock:GOOG', stockPrice);

    // Emit to all WebSocket clients
    io.emit('stock:update', { symbol: 'GOOG', price: stockPrice });
  } catch (error) {
    console.error('Error fetching stock price:', error.message);
  }
}

setInterval(fetchAndBroadcastStock, 5000);

// WebSocket connection
io.on('connection', (socket) =&amp;gt; {
  console.log('Client connected:', socket.id);

  socket.on('disconnect', () =&amp;gt; {
    console.log('Client disconnected:', socket.id);
  });
});

server.listen(3000, () =&amp;gt; console.log('Server running on http://localhost:3000'));
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;frontend-angular-socket-io-client-&quot;&gt;Frontend (Angular + Socket.IO-client)&lt;/h3&gt;
&lt;h4 id=&quot;1-install-socket-io-client&quot;&gt;1. Install &lt;code&gt;socket.io-client&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;npm install socket.io-client&lt;/p&gt;
&lt;h4 id=&quot;2-socket-service&quot;&gt;2. Socket Service&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// socket.service.ts
import { Injectable } from '@angular/core';
import { io, Socket } from 'socket.io-client';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class SocketService {
  private socket: Socket;

  constructor() {
    this.socket = io('http://localhost:3000'); // or environment variable
  }

  getStockUpdates(): Observable&amp;lt;any&amp;gt; {
    return new Observable(observer =&amp;gt; {
      this.socket.on('stock:update', (data) =&amp;gt; {
        observer.next(data);
      });

      return () =&amp;gt; this.socket.disconnect();
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-component&quot;&gt;3. Component&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// app.component.ts
import { Component, OnInit } from '@angular/core';
import { SocketService } from './socket.service';

@Component({
  selector: 'app-root',
  template: `&amp;lt;div *ngIf=&quot;price&quot;&amp;gt;GOOG: ${{ price }}&amp;lt;/div&amp;gt;`
})
export class AppComponent implements OnInit {
  price: number;

  constructor(private socketService: SocketService) {}

  ngOnInit() {
    this.socketService.getStockUpdates().subscribe(data =&amp;gt; {
      this.price = data.price;
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;production-best-practices&quot;&gt;Production Best Practices&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use environment variables&lt;/strong&gt; (&lt;code&gt;.env&lt;/code&gt;) for API keys and URLs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rate-limit external API calls&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use Redis as pub/sub if horizontally scaling backend&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable HTTPS and use secure WebSocket (WSS)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Add authentication for client connections (JWT on handshake)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-reconnect on frontend using Socket.IO’s built-in options&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dockerize the backend for easy deployment&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Monitor with tools like Prometheus + Grafana&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;optional-enhancements&quot;&gt;Optional Enhancements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;Kafka&lt;/strong&gt; if you want true event streaming across services&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;historical price chart&lt;/strong&gt; using D3.js or Chart.js&lt;/li&gt;
&lt;li&gt;Support multiple stock symbols (not just GOOG)&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;RxJS Subjects&lt;/strong&gt; in Angular to create a real-time service layer&lt;/li&gt;
&lt;li&gt;Store recent updates in a database (PostgreSQL + TimescaleDB for time series)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perfect start to add functional stock updates: Achieve a production-ready, scalable solution with functionality, scalability, and maintainability.&lt;/p&gt;
</description>
<category>Full-stack Dev</category>
<guid isPermaLink="true">https://coderlegion.com/3336/how-to-add-functional-stock-updates-achieve-a-production-ready-and-scalable-solution</guid>
<pubDate>Sat, 14 Jun 2025 09:59:49 +0000</pubDate>
</item>
<item>
<title>How to Build a Dual-LLM Chat Application with Next.js, Python, and WebSocket Streaming</title>
<link>https://coderlegion.com/1304/how-to-build-a-dual-llm-chat-application-with-next-js-python-and-websocket-streaming</link>
<description>&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;In the age of rapid AI advancement, software engineers are frequently tasked with building sophisticated chatbots. This article provides a practical guide to developing a &lt;strong&gt;real-time, response-streaming chatbot from scratch&lt;/strong&gt; using &lt;strong&gt;transformer models&lt;/strong&gt;, &lt;strong&gt;autoencoding (BERT family)&lt;/strong&gt;, and &lt;strong&gt;autoregressive (GPT family)&lt;/strong&gt; techniques. We'll learn how to build a chatbot capable of &lt;strong&gt;contextual conversations&lt;/strong&gt;, processing user &lt;strong&gt;text and image/PDF uploads&lt;/strong&gt; for enhanced understanding.  We'll utilize &lt;strong&gt;Python (aiohttp)&lt;/strong&gt; and &lt;strong&gt;React (Next.js)&lt;/strong&gt; to deliver a seamless, interactive experience. Let's dive in!&lt;/p&gt;
&lt;h3 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h3&gt;
&lt;p&gt;No prior expertise is strictly necessary, but some foundation in AI, software engineering, Python coding, and frontend development with a framework like React, Svelte, Vue, or Angular will be beneficial. &lt;strong&gt;If you're new to &lt;code&gt;aiohttp&lt;/code&gt; or &lt;code&gt;Svelte&lt;/code&gt;, we highly suggest exploring &lt;a rel=&quot;nofollow&quot; href=&quot;https://johnowolabiidogun.dev/blog?series=679c6ddc40997d46a81bd527&quot; title=&quot;Building an AI-Powered Financial Data Analyzer Series&quot;&gt;this previous article series&lt;/a&gt; as a helpful primer.&lt;/strong&gt;  Don't worry if you're not an expert (I ain't).&lt;/p&gt;
&lt;p&gt;To set up your project, first create a root folder &lt;code&gt;genai-chatbot&lt;/code&gt; and then navigate into the &lt;code&gt;backend&lt;/code&gt; subdirectory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```sh
mkdir genai-chatbot &amp;amp;&amp;amp; cd genai-chatbot &amp;amp;&amp;amp; mkdir backend &amp;amp;&amp;amp; cd backend
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;code&gt;backend&lt;/code&gt; directory, create a Python virtual environment and install dependencies from &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```sh
python3 -m venv virtualenv &amp;amp;&amp;amp; source virtualenv/bin/activate &amp;amp;&amp;amp; pip install -r requirements.txt
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ensure you create a &lt;code&gt;requirements.txt&lt;/code&gt; file in the &lt;code&gt;backend&lt;/code&gt; directory with the following content:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```txt
aiohttp
aiodns 
transformers 
torch 
torch-vision
pymupdf
pytesseract
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the frontend, navigate to the root directory (&lt;code&gt;genai-chatbot&lt;/code&gt;) and use &lt;code&gt;create-next-app&lt;/code&gt; to generate a React frontend with TypeScript:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```sh
cd ..
npx create-next-app@latest react-frontend --typescript --eslint --app
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Follow the prompts from &lt;code&gt;create-next-app&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;source-code&quot;&gt;Source code&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;Due to restrictions here, refer to the code repository for each file discussed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Sirneij/genai-chatbot&quot; title=&quot;Sirneij/genai-chatbot&quot;&gt;github/Sirneij/genai-chatbot&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementation&lt;/h3&gt;
&lt;h4 id=&quot;step-1-theory---autoregressive-vs-autoencoding-models&quot;&gt;Step 1: Theory - Autoregressive vs Autoencoding models&lt;/h4&gt;
&lt;p&gt;Two primary approaches emerge within the &lt;a rel=&quot;nofollow&quot; href=&quot;https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf&quot; title=&quot;Attention Is All You Need&quot;&gt;transformer model architecture&lt;/a&gt;: &lt;strong&gt;autoregressive&lt;/strong&gt; and &lt;strong&gt;autoencoding&lt;/strong&gt;. &lt;strong&gt;Autoregressive models&lt;/strong&gt;, like those using the &lt;strong&gt;decoder&lt;/strong&gt; component of a transformer, predict the next word (token) in a sequence based solely on the preceding words (a strictly left-to-right approach).  This sequential generation method is ideal for tasks like text generation and &lt;strong&gt;response streaming&lt;/strong&gt;. In contrast, &lt;strong&gt;autoencoding models&lt;/strong&gt; (also known as &lt;strong&gt;masked language models&lt;/strong&gt;) leverage the &lt;strong&gt;encoder&lt;/strong&gt; part of the transformer. They operate &lt;strong&gt;bidirectionally&lt;/strong&gt;, considering both preceding and subsequent words in a sentence to understand the context and produce representations.  Refer to &lt;a rel=&quot;nofollow&quot; href=&quot;https://huggingface.co/transformers/v3.1.0/model_summary.html#autoregressive-models&quot; title=&quot;Summary of the models&quot;&gt;Hugging Face's model summary&lt;/a&gt; for a detailed comparison.  &lt;strong&gt;Pretraining methodology&lt;/strong&gt; is a key differentiator: autoregressive models are pretrained to predict the next token, making them naturally suited for text generation, while autoencoding models excel at contextual understanding, making them strong for tasks like &lt;strong&gt;question answering based on documents&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this project, we will practically explore the distinct text generation capabilities of both model types in real-time. We will use &lt;a rel=&quot;nofollow&quot; href=&quot;https://huggingface.co/microsoft/Phi-3-mini-4k-instruct&quot; title=&quot;microsoft/Phi-3-mini-4k-instruct&quot;&gt;&lt;code&gt;microsoft/Phi-3-mini-4k-instruct&lt;/code&gt;&lt;/a&gt; (autoregressive) and &lt;a rel=&quot;nofollow&quot; href=&quot;https://huggingface.co/deepset/roberta-base-squad2&quot; title=&quot;roberta-base for Extractive QA&quot;&gt;&lt;code&gt;deepset/roberta-base-squad2&lt;/code&gt;&lt;/a&gt; (autoencoding) for demonstration, acknowledging resource limitations and focusing on showcasing the core differences.&lt;/p&gt;
&lt;h4 id=&quot;step-2-python-asynchronous-backend-with-aiohttp&quot;&gt;Step 2: Python asynchronous backend with aiohttp&lt;/h4&gt;
&lt;p&gt;We'll start with the project structure from &lt;a rel=&quot;nofollow&quot; href=&quot;https://johnowolabiidogun.dev/blog/asynchronous-server-building-and-rigorously-testing-a-websocket-and-http-server-eb297c/67b0ab3c7a900ac23e502c51&quot; title=&quot;Asynchronous Server: Building and Rigorously Testing a WebSocket and HTTP Server&quot;&gt;Building and Rigorously Testing a WebSocket and HTTP Server&lt;/a&gt;. Populate &lt;code&gt;src/app/__init__.py&lt;/code&gt; with the following code, noting the key adaptations for our chatbot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```python
import json
from weakref import WeakSet

from aiohttp import WSCloseCode, web
from aiohttp.web import Request, Response, WebSocketResponse

from src.utils.auto_chat_engine import (
    cleanup_auto_model,
    gpt_question_and_answer,
    prepare_auto_tokenizer_and_model,
)
from src.utils.chat_engine import (
    prepare_qa_tokenizer_and_model,
    squad_question_answering,
)
from src.utils.extract import extract_text_from_file
from src.utils.settings import base_settings

WEBSOCKETS = web.AppKey('websockets', WeakSet[WebSocketResponse])
...

async def extract_text(request: Request) -&amp;gt; Response:
    &quot;&quot;&quot;Extract text from PDF and image files.&quot;&quot;&quot;
    data = await request.post()
    files = data.getall('file')
    if not files:
        return web.json_response({'error': 'No files provided'}, status=400)

    extracted_text = []
    for file in files:
        if file.content_type not in ['application/pdf', 'image/jpeg', 'image/png']:
            return web.json_response({'error': 'Invalid file type'}, status=400)

        text = await extract_text_from_file(file.file, file.content_type)
        extracted_text.append(text)

    base_settings.context = '\n'.join(extracted_text)

    return web.json_response({'success': 'Text extracted successfully'})


async def chat_handler(request: Request) -&amp;gt; Response:
    &quot;&quot;&quot;Handle WebSocket connections.&quot;&quot;&quot;
    ws = WebSocketResponse()
    await ws.prepare(request)

    request.app[WEBSOCKETS].add(ws)

    async for msg in ws:
        if msg.type == web.WSMsgType.TEXT:
            try:
                data = json.loads(msg.data)
                question_type = data.get('type')
                question = data.get('question', '').strip()
                if not question:
                    await ws.send_str('Error: No question provided.')
                    continue

                if question_type == 'auto':
                    # Stream response token by token.
                    async for token in gpt_question_and_answer(question):
                        await ws.send_json({'answer': token})
                elif question_type == 'masked':
                    # Use squad question answering (non-streamed).
                    answer = await squad_question_answering(question)
                    await ws.send_json({'answer': answer})
                else:
                    await ws.send_str('Error: Unknown question type.')
            except Exception as e:
                await ws.send_str(f'Error processing message: {str(e)}')
        elif msg.type == web.WSMsgType.ERROR:
            request.app[WEBSOCKETS].remove(ws)
            break

    request.app[WEBSOCKETS].remove(ws)

    return ws


def init_app() -&amp;gt; web.Application:
    &quot;&quot;&quot;Initialize the application.&quot;&quot;&quot;
    app = web.Application()

    # Add routes
    app.router.add_post('/api/extract', extract_text)
    app.router.add_get('/chat', chat_handler)

    # Add startup/cleanup handlers
    app.on_startup.append(start_background_tasks)
    app.on_shutdown.append(cleanup_app)

    return app
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;__init__.py&lt;/code&gt; file builds upon the structure from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://johnowolabiidogun.dev/blog?series=679c6ddc40997d46a81bd527&quot; title=&quot;Building an AI-Powered Financial Data Analyzer Series&quot;&gt;recommended series&lt;/a&gt;. The key differences for our chatbot are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;start_background_tasks&lt;/code&gt; (on startup) loads AI models, and &lt;code&gt;cleanup_app&lt;/code&gt; (on shutdown) unloads them, improving resource handling.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;extract_text&lt;/code&gt; handler accepts and processes multiple uploaded files to create a combined context.&lt;/li&gt;
&lt;li&gt;We use direct &lt;code&gt;aiohttp&lt;/code&gt; WebSocket APIs in &lt;code&gt;chat_handler&lt;/code&gt;. We support &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;masked&lt;/code&gt; types representing the use of autogenerative and masked language models respectively.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, let's delve into the files within the &lt;code&gt;src/utils&lt;/code&gt; directory, starting with &lt;code&gt;settings.py&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;settings.py&lt;/code&gt; file primarily houses our &lt;code&gt;logger&lt;/code&gt; configuration and defines several important constants used in the application, including the system prompt, the default language model (&lt;code&gt;MODEL_NAME&lt;/code&gt;), and the question answering model (&lt;code&gt;QA_MODEL_NAME&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Let's examine &lt;code&gt;base.py&lt;/code&gt; next. &lt;code&gt;get_device&lt;/code&gt;  intelligently detects the available hardware and returns the appropriate PyTorch device (CUDA GPU, Apple Metal (MPS), or CPU) along with a descriptive string. &lt;code&gt;get_stopping_strings&lt;/code&gt; plays a crucial role in prompt construction for the autoregressive model. It dynamically generates a prompt and a list of stopping strings based on the question type and optional context. The prompt instructs the model to provide a concise answer using Markdown formatting and KaTeX for mathematical expressions. A key challenge with autoregressive models is their tendency to generate repetitive text. To mitigate this, the prompt explicitly instructs the model to conclude its response with the &quot;§&quot; symbol, an uncommon character chosen to signal the end of the answer. The application then programmatically halts text generation upon encountering this symbol. While using the model's native end-of-sequence token would be ideal, I had no luck with it.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;auto_chat_engine.py&lt;/code&gt; file is the central component responsible for generating text using the configured language model. It orchestrates the model's loading, manages the text generation process, and handles device-specific optimizations.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;prepare_auto_tokenizer_and_model&lt;/code&gt; initializes the tokenizer and model. To avoid redundant or repetitive loading, we used global variables and adapted the loading process based on the available device (CPU, MPS, CUDA). &lt;/p&gt;
&lt;p&gt;&lt;code&gt;torch.quantization.quantize_dynamic&lt;/code&gt; is a nifty way to &lt;a rel=&quot;nofollow&quot; href=&quot;https://pytorch.org/blog/quantization-in-practice/&quot; title=&quot;Practical Quantization in PyTorch&quot;&gt;quantize&lt;/a&gt; the model so that it will run faster and require lower memory. If your machine supports &lt;code&gt;cuda&lt;/code&gt;, you will need to add your block in the code. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;cleanup_auto_model&lt;/code&gt; primarily releases the model and tokenizer from memory. This is particularly important on memory-constrained devices like those with Apple Silicon (MPS), where memory leaks can quickly degrade performance. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;top_k_top_p_filtering&lt;/code&gt;  implements two common techniques for controlling the diversity and quality of generated text. Top-k filtering limits the model's choices to the k most likely tokens, while top-p (nucleus) sampling considers the smallest set of tokens whose cumulative probability exceeds p. In simple terms, they help to strike a balance between generating creative and coherent text by preventing the model from generating nonsensical or irrelevant tokens. &lt;/p&gt;
&lt;p&gt;The &lt;code&gt;stream_chat_response&lt;/code&gt; function is the heart of our real-time chatbot's text generation.  It takes a &lt;code&gt;prompt&lt;/code&gt;, the &lt;code&gt;model&lt;/code&gt;, and configurations to generate streaming text output.  For performance, within the generation loop, we:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Optimize Device Usage:&lt;/strong&gt; Move model parameters to the active device for faster access.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disable Gradients:&lt;/strong&gt;  Use &lt;code&gt;torch.no_grad()&lt;/code&gt; to skip unnecessary gradient calculations during inference.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable Auto-Precision:&lt;/strong&gt; Utilize &lt;code&gt;torch.autocast&lt;/code&gt; for faster, mixed-precision operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The generation process automatically stops when it encounters our stopping character (code lines 151-152). To ensure smooth streaming, the function also briefly releases memory between tokens. Finally, after generating the complete response, &lt;code&gt;stream_chat_response&lt;/code&gt; yields &lt;code&gt;[END]&lt;/code&gt; to signal to the frontend that the stream is complete.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gpt_question_and_answer&lt;/code&gt; serves as a high-level interface for generating answers to questions. It retrieves the appropriate prompt and stopping strings using &lt;code&gt;get_stopping_strings&lt;/code&gt; and then calls &lt;code&gt;stream_chat_response&lt;/code&gt; to generate the text. You can modify the parameters here to your taste.&lt;/p&gt;
&lt;p&gt;Finally, let's examine the &lt;code&gt;chat_engine.py&lt;/code&gt; file. This module leverages pre-trained BERT-based models for extracting answers from a given context. &lt;code&gt;prepare_qa_tokenizer_and_model&lt;/code&gt; initializes the question-answering pipeline. The primary motivation behind using a global &lt;code&gt;QA_PIPELINE&lt;/code&gt;, as previously stated, is to avoid repeatedly loading the model, which is a resource-intensive operation. In &lt;code&gt;squad_question_answering&lt;/code&gt;,  a key design decision here is the enforcement of a context. BERT-based models, while powerful, generally perform best when given a specific context to ground their answers. To prevent blocking the main thread, the actual question-answering process is offloaded to a separate asynchronous thread using &lt;code&gt;asyncio.to_thread&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;step-3-building-a-react-frontend-with-next-js-and-tailwind-css&quot;&gt;Step 3: Building a React Frontend with Next.js and Tailwind CSS&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3spw67cquab3lcl8dfbz.png&quot; alt=&quot;Home page of the app&quot;&gt;&lt;/p&gt;
&lt;p&gt;While our server backend is functional and can be interacted with via command-line tools like &lt;code&gt;wscat&lt;/code&gt; (using a command such as &lt;code&gt;wscat -c ws://localhost:PORT/chat&lt;/code&gt; followed by a prompt like &lt;code&gt;{&quot;type&quot;: &quot;auto&quot;, &quot;question&quot;: &quot;Write Python code for Fibonacci sequence&quot;}&lt;/code&gt;), this approach is not user-friendly. To make our AI chatbot accessible to a wider audience, including those unfamiliar with the terminal, we need a graphical user interface. We'll leverage Next.js, a React framework known for its performance and developer experience, along with Tailwind CSS for styling.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuqpwlu4wdh70jvb0265.png&quot; alt=&quot;Brief conversation with the app&quot;&gt;&lt;/p&gt;
&lt;p&gt;Our frontend application consists of a single page with a few key components. Let's start by examining &lt;code&gt;react-frontend/src/app/layout.tsx&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This &lt;code&gt;layout.tsx&lt;/code&gt; file defines the root layout of our Next.js application. It's largely based on the default code generated by &lt;code&gt;create-next-app&lt;/code&gt; and enhanced with &lt;a rel=&quot;nofollow&quot; href=&quot;https://tailwindcss.com/docs/installation/framework-guides/nextjs&quot; title=&quot;Install Tailwind CSS with Next.js&quot;&gt;Tailwind CSS integration&lt;/a&gt;. We've also integrated &lt;a rel=&quot;nofollow&quot; href=&quot;https://katex.org/docs/node&quot; title=&quot;KaTeX - Node.js installation&quot;&gt;KaTeX&lt;/a&gt; for rendering mathematical expressions (remember to install the &lt;code&gt;katex&lt;/code&gt; package and its TypeScript definitions, as well as &lt;a rel=&quot;nofollow&quot; href=&quot;https://marked.js.org/&quot; title=&quot;MarkedJS - A low-level markdown compiler for parsing markdown without caching or blocking for long periods&quot;&gt;marked.js&lt;/a&gt; for Markdown processing). The &lt;code&gt;ThemeSwitcher&lt;/code&gt; component, responsible for toggling between light and dark themes, is also included.&lt;/p&gt;
&lt;p&gt;For Svelte developers, React's &lt;code&gt;useEffect&lt;/code&gt; hook serves a similar purpose to Svelte 5's &lt;code&gt;$effect&lt;/code&gt; block. Both allow you to run code in response to changes (in &lt;code&gt;useEffect&lt;/code&gt; you need to list the dependencies, you don't need that in Svelte), and critically, both provide a safe context for interacting with HTML elements.&lt;/p&gt;
&lt;p&gt;Now is the turn is &lt;code&gt;react-frontend/src/app/page.tsx&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This file represents the main page component of our chat application, housing the core logic for message handling and UI rendering. The &lt;code&gt;Home&lt;/code&gt; component manages the chat interface, including displaying messages, handling user input, and communicating with the backend. The &lt;code&gt;handleSend&lt;/code&gt; function adds a user message and a loading message to the state, while &lt;code&gt;handleBotMessage&lt;/code&gt; updates the UI with the bot's responses as they stream in.&lt;/p&gt;
&lt;p&gt;The custom &lt;code&gt;useWebSocket&lt;/code&gt; hook encapsulates all the WebSocket logic, including connection management, message handling, and error handling.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;handleSend&lt;/code&gt; function adds a temporary &quot;loading&quot; message to the chat interface. This is a simple but effective UI trick to provide immediate feedback to the user while waiting for the AI bot's response. Without this, the user might perceive a delay or lack of responsiveness which is unwanted. &lt;code&gt;handleBotMessage&lt;/code&gt; function is designed to handle the streaming responses from the AI bot. It efficiently updates the chat interface by appending new content to the last bot message. The &lt;code&gt;isComplete&lt;/code&gt; flag, triggered by the &lt;code&gt;&quot;[END]&quot;&lt;/code&gt; signal from the backend, ensures that the loading indicator is removed when the bot finishes generating its response. Why &lt;code&gt;useCallback&lt;/code&gt; in &lt;code&gt;handleBotMessage&lt;/code&gt;? Its primary reason is to prevent unnecessary re-renders of components that depend on these functions and it does that by memoizing them so that they only change when their dependencies change.&lt;/p&gt;
&lt;p&gt;To wrap up, let's look at the &lt;code&gt;react-frontend/src/app/ui/chat/ChatContainer.tsx&lt;/code&gt; and &lt;code&gt;react-frontend/src/app/ui/chat/ChatInput.tsx&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ChatContainer&lt;/code&gt; component renders the list of &lt;code&gt;ChatMessage&lt;/code&gt; components. It's a straightforward component that iterates over the messages and displays each one.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ChatMessage&lt;/code&gt; component is responsible for rendering individual chat messages. The key feature of this component is its use of &lt;code&gt;marked.js&lt;/code&gt; to render Markdown content, with extensions for syntax highlighting (using &lt;code&gt;highlight.js&lt;/code&gt;) and math rendering (using &lt;code&gt;KaTeX&lt;/code&gt;). The component also includes logic to display a &quot;thinking&quot; animation while the bot is generating a response.&lt;/p&gt;
&lt;p&gt;Lastly, let's look at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Sirneij/genai-chatbot/blob/main/react-frontend/src/app/ui/chat/ChatInput.tsx&quot; title=&quot;react-frontend/src/app/ui/chat/ChatInput.tsx&quot;&gt;&lt;code&gt;react-frontend/src/app/ui/chat/ChatInput.tsx&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It provides the user interface for entering and sending messages. It includes a text input, controls for toggling &quot;Masked&quot; and &quot;Auto&quot; modes, and a file upload button (you must select the &lt;code&gt;masked&lt;/code&gt; mode to upload). The component was inspired by X's Grok 3, .&lt;/p&gt;
&lt;p&gt;An important to note is that in &lt;code&gt;handleFileUpload&lt;/code&gt;, I used a &lt;a rel=&quot;nofollow&quot; href=&quot;https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations&quot; title=&quot;Server Actions and Mutations&quot;&gt;NextJS action&lt;/a&gt; (&lt;code&gt;uploadFiles&lt;/code&gt;) to communicate with the server for files upload.&lt;/p&gt;
&lt;p&gt;The key reason for using a server action is to avoid CORS errors such as &lt;code&gt;Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ...&lt;/code&gt;. By executing the upload logic on the server, we bypass the browser's same-origin policy and can communicate with the backend API without requiring CORS configuration.&lt;/p&gt;
&lt;p&gt;I am sorry for the long article. I didn't want to split so I can be forced to just finish it at a go. There are still a couple of cleanups to do but I will leave those to you. Bye for now.&lt;/p&gt;
&lt;h3 id=&quot;outro&quot;&gt;Outro&lt;/h3&gt;
&lt;p&gt;Enjoyed this article? I'm a Software Engineer, Technical Writer, and Technical Support Engineer actively seeking new opportunities, particularly in areas related to web security, finance, healthcare, and education. If you think my expertise aligns with your team's needs, let's chat! You can find me on &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/john-owolabi-idogun/&quot;&gt;LinkedIn&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/Sirneij&quot;&gt;X&lt;/a&gt;. I am also an [email](mailto:&lt;em&gt;Emails are not allowed&lt;/em&gt;) away.&lt;/p&gt;
&lt;p&gt;If you found this article valuable, consider sharing it with your network to help spread the knowledge!&lt;/p&gt;
</description>
<category>Full-stack Dev</category>
<guid isPermaLink="true">https://coderlegion.com/1304/how-to-build-a-dual-llm-chat-application-with-next-js-python-and-websocket-streaming</guid>
<pubDate>Thu, 27 Feb 2025 18:45:04 +0000</pubDate>
</item>
<item>
<title>Building the Backend of Chatty - A Real-Time MERN WebSocket Chat App</title>
<link>https://coderlegion.com/1193/building-the-backend-of-chatty-a-real-time-mern-websocket-chat-app</link>
<description>&lt;p&gt; Chatty is a real-time chat application built using the MERN stack and WebSockets to enable seamless and instant communication. A strong backend is essential for ensuring real-time messaging, authentication, and database management, creating a reliable and scalable chat experience.&lt;/p&gt;
&lt;p&gt;In this blog, I’ll cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ Setting up WebSockets with socket.io for real-time updates &lt;/li&gt;
&lt;li&gt;✅ JWT authentication for secure user sessions &lt;/li&gt;
&lt;li&gt;✅ Storing messagesvefficiently in MongoDB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is only an overview of the code; for the complete implementation, check out the GitHub repo linked at the end! &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Setting Up the Backend&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The backend is built using Node.js &amp;amp; Express.js. To get started, install the necessary dependencies:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;br&gt;
 &lt;code&gt;npm install express mongoose dotenv socket.io jsonwebtoken bcryptjs cors&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Initializing the server:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import express from &quot;express&quot;;
import http from &quot;http&quot;;
import { Server } from &quot;socket.io&quot;;
import mongoose from &quot;mongoose&quot;;
import dotenv from &quot;dotenv&quot;;
import cors from &quot;cors&quot;;
import authRoutes from &quot;./routes/authRoutes.js&quot;;
import chatRoutes from &quot;./routes/chatRoutes.js&quot;;
dotenv.config();
const app = express();
const server = http.createServer(app);
const io = new Server(server, { cors: { origin: &quot;*&quot; } });
app.use(express.json());
app.use(cors());
app.use(&quot;/api/auth&quot;, authRoutes);
app.use(&quot;/api/chat&quot;, chatRoutes);
server.listen(5000, () =&amp;gt; console.log(&quot;Server running on port 5000&quot;));
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Implementing WebSocket for Real-Time Messaging&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;WebSockets allow for bi-directional real-time communication, ensuring that messages are instantly delivered to all connected users.&lt;/p&gt;
&lt;p&gt;`io.on(&quot;connection&quot;, (socket) =&amp;gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(&quot;User connected:&quot;, socket.id);
socket.on(&quot;sendMessage&quot;, (messageData) =&amp;gt; {
    io.emit(&quot;receiveMessage&quot;, messageData); // Broadcast message to all clients
});
socket.on(&quot;disconnect&quot;, () =&amp;gt; {
    console.log(&quot;User disconnected&quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}); `&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Implementing JWT Authentication&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To ensure user security, we implement JWT-based authentication for login and protected routes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;User Model (models/User.js)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;`import mongoose from &quot;mongoose&quot;;&lt;br&gt;
import bcrypt from &quot;bcryptjs&quot;;&lt;br&gt;
const UserSchema = new mongoose.Schema({&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;username: { type: String, required: true, unique: true },
password: { type: String, required: true }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;br&gt;
UserSchema.pre(&quot;save&quot;, async function (next) {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (!this.isModified(&quot;password&quot;)) return next();
this.password = await bcrypt.hash(this.password, 10);
next();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;br&gt;
export default mongoose.model(&quot;User&quot;, UserSchema);&lt;br&gt;
`&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auth Controllers (controllers/authController.js)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;`import jwt from &quot;jsonwebtoken&quot;;&lt;br&gt;
import bcrypt from &quot;bcryptjs&quot;;&lt;br&gt;
import User from &quot;../models/User.js&quot;;&lt;br&gt;
dotenv.config();&lt;br&gt;
export const registerUser = async (req, res) =&amp;gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try {
    const { username, password } = req.body;
    const newUser = new User({ username, password });
    await newUser.save();
    res.status(201).json({ message: &quot;User registered successfully&quot; });
} catch (error) {
    res.status(500).json({ error: error.message });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;br&gt;
export const loginUser = async (req, res) =&amp;gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try {
    const { username, password } = req.body;
    const user = await User.findOne({ username });
    if (!user || !await bcrypt.compare(password, user.password)) {
        return res.status(401).json({ message: &quot;Invalid credentials&quot; });
    }
    const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: &quot;1h&quot; });
    res.json({ token, user });
} catch (error) {
    res.status(500).json({ error: error.message });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}; `&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Storing Messages in MongoDB&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Chat messages need to be stored persistently so users can retrieve past conversations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Model (models/Message.js)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;`import mongoose from &quot;mongoose&quot;;&lt;br&gt;
const MessageSchema = new mongoose.Schema({&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sender: { type: mongoose.Schema.Types.ObjectId, ref: &quot;User&quot; },
content: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;br&gt;
export default mongoose.model(&quot;Message&quot;, MessageSchema);`&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message Controller (controllers/chatController.js)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;`import Message from &quot;../models/Message.js&quot;;&lt;br&gt;
export const saveMessage = async (req, res) =&amp;gt; {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try {
    const { sender, content } = req.body;
    const message = new Message({ sender, content });
    await message.save();
    res.status(201).json({ message: &quot;Message saved successfully&quot; });
} catch (error) {
    res.status(500).json({ error: error.message });
}`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Final Thoughts &amp;amp; Contribution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; That’s how Chatty’s backend is structured! We covered:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Real-time WebSockets for instant messaging&lt;/li&gt;
&lt;li&gt;JWT authentication to enhance security&lt;/li&gt;
&lt;li&gt;Efficient message storage in MongoDB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; This is only an overview of the code; for the complete implementation, check out the GitHub repo! The full repository contains additional optimizations, error handling, and best practices to ensure the app runs smoothly at scale.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Yasir761/Chatty&quot;&gt;Chatty Repo&lt;/a&gt;&lt;/p&gt;
</description>
<category>Backend Dev</category>
<guid isPermaLink="true">https://coderlegion.com/1193/building-the-backend-of-chatty-a-real-time-mern-websocket-chat-app</guid>
<pubDate>Fri, 21 Feb 2025 10:19:08 +0000</pubDate>
</item>
<item>
<title>Introduction to Chatty - A Real-Time MERN WebSocket Chat App</title>
<link>https://coderlegion.com/1169/introduction-to-chatty-a-real-time-mern-websocket-chat-app</link>
<description>&lt;p&gt; Communication has evolved significantly over the years, and real-time chat applications have become a necessity in the digital world. Whether for personal conversations, team collaborations, or customer support, users expect instant messaging with zero lag. As a MERN stack developer, I wanted to build a scalable and efficient chat app that delivers a seamless user experience. That’s how Chatty was born! In this blog post, I’ll introduce you to Chatty, its core features, the technology stack behind it, and why WebSockets are a game-changer for real-time applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is Chatty?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; Chatty is a real-time chat application built using the MERN stack (MongoDB, &lt;img src=&quot;https://github.com/Yasir761/Chatty&quot; alt=&quot;&quot;&gt;Express.js, React, and Node.js) with WebSockets to enable instant, two-way communication. Unlike traditional chat apps that rely on HTTP polling (which can be slow and inefficient), Chatty leverages WebSockets to create a persistent connection, allowing users to send and receive messages in real-time without delays.&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;Key Features of Chatty:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instant Messaging: Powered by WebSockets, ensuring fast and real-time&lt;br&gt;
communication .  &lt;/li&gt;
&lt;li&gt;User Authentication with JWT: Secure login system to protect user data .   &lt;/li&gt;
&lt;li&gt;Optimized Backend: Efficient handling of connections and message storage. &lt;br&gt;
 -Dockerized Deployment: Easily scalable and deployable with Docker containers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Why Did I Build Chatty?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As a developer, I wanted to tackle some of the biggest challenges in real-time communication:&lt;/p&gt;
&lt;p&gt;✅ Latency Issues: Many chat apps experience delays in delivering messages. WebSockets allow a persistent full-duplex connection, ensuring messages are delivered instantly without waiting for a new HTTP request.&lt;/p&gt;
&lt;p&gt;✅ Efficient Data Handling: Traditional chat applications send repeated HTTP requests (polling) to check for new messages. This approach is resource-intensive and inefficient. With WebSockets, a single connection remains open, drastically reducing overhead.&lt;/p&gt;
&lt;p&gt;✅ Secure Authentication: Handling user authentication securely is crucial. I implemented JWT-based authentication, ensuring only authorized users can access chat rooms and messages.&lt;/p&gt;
&lt;p&gt;✅ Scalability: With Dockerized deployment, Chatty can run in isolated containers, making it easy to scale across multiple servers when user traffic grows.&lt;/p&gt;
&lt;p&gt;Building Chatty helped me deepen my understanding of WebSockets, authentication, and containerization while applying best practices for real-world application development.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tech Stack Behind Chatty&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To create a high-performance and scalable real-time chat application, I chose the following technologies:&lt;/p&gt;
&lt;p&gt; Frontend: React.js (for an interactive and smooth user experience)&lt;/p&gt;
&lt;p&gt; Backend: Node.js &amp;amp; Express.js (handling real-time messaging with WebSockets)&lt;/p&gt;
&lt;p&gt; Database: MongoDB (storing user messages, conversations, and profiles)&lt;/p&gt;
&lt;p&gt; WebSockets: Socket.io (enabling real-time chat functionality)&lt;/p&gt;
&lt;p&gt; Authentication: JWT (ensuring secure login and user validation)&lt;/p&gt;
&lt;p&gt; Docker: Containerizing the app for better deployment, scalability, and maintainability&lt;/p&gt;
&lt;p&gt;Each of these technologies plays a crucial role in making Chatty efficient, scalable, and user-friendly. By combining React, WebSockets, and Docker, I was able to build a real-time chat app that is both performant and easy to deploy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contribute to Chatty&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; Chatty is open-source, and I’d love for you to check it out! You can find the code on GitHub:&lt;/p&gt;
&lt;p&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Yasir761/Chatty&quot;&gt;Chatty Github Repo&lt;/a&gt;⭐&lt;/p&gt;
&lt;p&gt;If you find this project helpful, please give it a star ⭐ on GitHub and feel free to contribute! Whether it's fixing a bug, adding a feature, or improving documentation, all contributions are welcome. Let's build something amazing together! &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What’s Next?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is just the beginning! In the next blog post, I’ll dive into setting up the backend, where we’ll explore how to create a WebSocket server using Node.js, Express, and Socket.io. I’ll walk you through establishing real-time communication, handling events, and storing messages efficiently.&lt;/p&gt;
&lt;p&gt; Are you also building a chat app or curious about WebSockets? Let’s connect and discuss your experience! &lt;/p&gt;
</description>
<category>Full-stack Dev</category>
<guid isPermaLink="true">https://coderlegion.com/1169/introduction-to-chatty-a-real-time-mern-websocket-chat-app</guid>
<pubDate>Thu, 20 Feb 2025 12:01:31 +0000</pubDate>
</item>
</channel>
</rss>