Skip to content

Instantly share code, notes, and snippets.

@yogain123
Created July 21, 2019 07:43
Show Gist options
  • Save yogain123/5413f0258dbdfca3b3052a8729fd50dc to your computer and use it in GitHub Desktop.
Save yogain123/5413f0258dbdfca3b3052a8729fd50dc to your computer and use it in GitHub Desktop.
Extra Important
@yogain123
Copy link
Author

yogain123 commented May 8, 2020

Agile

Screen Shot 1941-11-07 at 9 58 15 PM

Headless Chrome

Screen Shot 2020-05-09 at 4 04 15 PM

@yogain123
Copy link
Author

yogain123 commented Aug 11, 2024

Web Assembly

What is WebAssembly (WASM)?

WebAssembly (WASM) is a technology that allows you to run high-performance code in the browser. It enables languages like C, C++, and Rust to be compiled and executed inside a web browser at near-native speed.

Why do we need WebAssembly?

Traditionally, browsers only understand JavaScript. If we want to run computationally heavy tasks (like video processing, gaming, or AI), JavaScript might not be fast enough. WebAssembly allows us to run code written in other languages efficiently.


How Does WebAssembly Work?

Step 1: Write Code in Another Language

Instead of writing JavaScript, you write code in languages like C, C++, or Rust.

Step 2: Compile to WebAssembly (.wasm file)

The code is compiled into a .wasm file, which is a binary format optimized for browsers.

Step 3: Load and Run in Browser

The .wasm file is loaded into JavaScript using the WebAssembly API, and then executed in the browser.


Example: Running C Code in the Browser with WebAssembly

Let's go step by step.

1. Write a Simple C Program (add.c)

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

2. Compile it to WebAssembly

Use Emscripten (a toolchain for compiling C/C++ to WASM):

emcc add.c -o add.wasm -s WASM=1 -s EXPORTED_FUNCTIONS="['_add']"

This generates add.wasm, which can be used in the browser.

3. Load the WASM File in JavaScript

fetch('add.wasm')
  .then(response => response.arrayBuffer())
  .then(bytes => WebAssembly.instantiate(bytes))
  .then(result => {
    const add = result.instance.exports.add;
    console.log("Result:", add(5, 10)); // Output: 15
  });
  • We fetch the .wasm file.
  • Convert it into binary format.
  • Use WebAssembly.instantiate() to load it.
  • Call the add function inside WebAssembly from JavaScript.

What Happens Internally?

  1. Compilation: The C code is converted into WebAssembly bytecode (.wasm).
  2. Loading: The .wasm file is loaded in the browser via JavaScript.
  3. Execution: The JavaScript calls the WebAssembly function and gets the result.

Benefits of WebAssembly

  • Faster than JavaScript for CPU-heavy tasks.
  • Supports multiple languages (C, C++, Rust, Python, etc.).
  • Runs in the browser securely (sandboxed).
  • Interoperable with JavaScript (you can call WebAssembly functions from JavaScript).

Where is WebAssembly Used?

  • Games: Running Unity and Unreal Engine games in the browser.
  • Image/Video Processing: Faster filters and effects.
  • AI & Machine Learning: Running TensorFlow models efficiently.
  • Cryptography: Faster encryption and hashing.

Final Thoughts

WebAssembly allows us to write high-performance applications in the browser using languages like C, C++, and Rust. It doesn’t replace JavaScript but works alongside it to handle heavy computations efficiently.

The key differences:

  • WebAssembly is about speed of execution, not parallelism.
  • Web Workers are about parallelism, using JavaScript.

How WebAssembly Works with V8
V8 has a WebAssembly compiler that takes .wasm binaries and compiles them into machine code.
The compiled WebAssembly code runs in a separate execution environment from JavaScript (but inside the same sandbox).
It interacts with JavaScript via the WebAssembly API, allowing JavaScript to call WASM functions.

@yogain123
Copy link
Author

yogain123 commented Jan 7, 2025

SaaS, PaaS, and IaaS

  • SaaS: Software you use directly (e.g., Gmail, Dropbox).
  • PaaS: Platform for developers to create apps (e.g., Heroku, Google App Engine).
  • IaaS: Virtualized infrastructure that you rent and manage (e.g., AWS, Google Cloud).

The main difference:

  • SaaS is fully managed software.
  • PaaS gives you tools to build apps.
  • IaaS gives you infrastructure to build everything from scratch.

@yogain123
Copy link
Author

yogain123 commented Jan 7, 2025

Hashing, Encryption, Encoding

Sure! Let's break down each term in simple, easy-to-understand language:

1. Hashing

  • Purpose: To transform data into a fixed-size string or value (called a hash) in such a way that it's irreversible. The main use of hashing is to check data integrity (e.g., ensuring that data has not been tampered with) and in password storage.

  • How it works: When you hash something, it gets turned into a unique string. Even a small change in the input will result in a completely different hash.

  • Example: When you hash a password, you store the hash (not the password). When someone logs in, you hash the entered password and compare it to the stored hash.

  • Key point: One-way process (cannot go back to the original data).

    Example: SHA256("password")5e884898da28047151d0e56f8dc6292773603d0d1e9b2d8b12537a208604f43d

  • Common algorithms: MD5, SHA-1, SHA-256, bcrypt, Argon2

2. Encryption

  • Purpose: To convert data into a form that only authorized people or systems can read, using a key. The main goal of encryption is security—it ensures that data can be securely transmitted or stored.

  • How it works: Data is transformed into a cipher (encrypted form), and only someone with the right decryption key can turn it back into its original form.

  • Example: Encrypting messages between two people using a key so that even if someone intercepts the message, they cannot read it without the decryption key.

  • Key point: Two-way process (you can encrypt and decrypt data with the proper key).

    Example: "Hello" → Encrypted with a key → @£$*%@!9sd → Decrypted back to "Hello" using the key.

  • Two types: Symmetric (same key): AES, DES, ChaCha20 Asymmetric (public/private keys): RSA, ECC

3. Encoding

  • Purpose: To convert data into a different format (usually for transmission or storage), so it can be easily understood or processed. The goal of encoding is compatibility.

  • How it works: It’s not meant to be secret—encoding is a reversible process. You can encode and then decode the data back to its original form.

  • Example: Converting a string like "Hello" into a base64 format for safe transmission over the internet.

  • Key point: Reversible process (you can decode the data back to its original form).

    Example: "Hello" → Encoded to base64 → SGVsbG8= → Decoded back to "Hello".

  • algorithms: Base64, ASCII, UTF-8, URL encoding

we can directly transmit plain string like "hello" why to encode? Problem: Data can sometimes include characters that are not universally recognized or safe to transmit.

Solution: Encoding ensures that data is converted into a format that can be safely transmitted across different systems or mediums.

Example: URLs or email addresses may include characters that have special meanings in certain protocols (e.g., &, =, or /). Encoding these characters ensures that they don’t interfere with the functionality of the system.

URL Encoding Example:

Original text: Hello & Welcome
URL-encoded: Hello%20%26%20Welcome
Without encoding, the & could be misinterpreted in a URL query string as a separator for multiple parameters.


In short:

  • Hashing: One-way transformation (cannot get the original data back).
  • Encryption: Two-way transformation (can get back to the original data with a key).
  • Encoding: Reversible (helps in data transmission).

@yogain123
Copy link
Author

yogain123 commented Jan 8, 2025

Clarity on Encryption

In symmetric encryption (single key):

  • One key is used for both encryption and decryption
  • Much faster than asymmetric encryption
  • Examples: AES, DES, 3DES

In asymmetric encryption (public/private key):

  • Uses two mathematically linked keys
  • Public key encrypts, private key decrypts
  • Slower than symmetric encryption
  • Examples: RSA, ECC

In practice, most systems use a hybrid approach:

  1. The actual data is encrypted using symmetric encryption (faster)
  2. The symmetric key is then encrypted using asymmetric encryption (more secure for transmission)
  3. The encrypted symmetric key is sent along with the encrypted data

For example, when you visit an HTTPS website:

  1. Your browser and the server use asymmetric encryption to securely exchange a symmetric session key
  2. All further communication during that session uses that symmetric key
  3. A new session key is generated for each connection

So it's not that the symmetric key "needs" public key encryption - rather, public key encryption is one secure method of exchanging symmetric keys between parties. There are other ways to share symmetric keys (like pre-shared keys), but public key infrastructure (PKI) is widely used because it scales well and doesn't require prior key exchange.

@yogain123
Copy link
Author

yogain123 commented Jan 23, 2025

Protocols (Mostly TCP/IP)

Understanding Protocols and Their Role

A protocol is like a set of rules or instructions that govern how data is sent and received over the internet. Each protocol serves a specific purpose and defines how devices (browsers, servers, email clients, etc.) communicate with each other.

When you type a URL in your browser (e.g., https://example.com), the protocol at the beginning (like http:// or https://) tells your browser how to communicate with the server hosting that website.


Key Protocols We Discussed

  1. HTTP/HTTPS (HyperText Transfer Protocol / Secure):
    • Purpose: Used for loading websites.
    • HTTP: Sends data in plain text. It's insecure because anyone intercepting the connection can read the data.
    • HTTPS: Adds encryption (using SSL/TLS) to ensure data is secure, protecting sensitive information like passwords or credit card details.
    • Example:
      • http://example.com → A non-secure website.
      • https://example.com → A secure website, often indicated by a padlock icon in the browser.

  1. TCP/IP (Transmission Control Protocol / Internet Protocol):
    • Purpose: These protocols form the foundation of the internet, handling how data is split into packets, sent across networks, and reassembled at the destination.
    • TCP: Ensures reliable delivery of data by verifying that all packets are received correctly.
    • IP: Handles the routing of packets (like choosing the best path for the data to travel).
    • Role in the Browser: While TCP/IP is used for every network communication, it’s not visible to you—it works behind the scenes.

  1. SMTP (Simple Mail Transfer Protocol):
    • Purpose: Used for sending emails.
    • How It Works: When you send an email from a client (like Gmail, Outlook), SMTP transfers the email from your computer to an outgoing mail server and then delivers it to the recipient's mail server.
    • Visible in Browser? No. SMTP is used for server-to-server communication after you submit an email, so it’s not visible in the browser or its network requests.

  1. IMAP (Internet Message Access Protocol):
    • Purpose: Used for retrieving emails from an email server.
    • How It Works: IMAP lets you access your emails from multiple devices by syncing with the mail server (e.g., viewing your inbox on both your phone and laptop).
    • Visible in Browser? No. Like SMTP, IMAP is used by email clients in the background, not by browsers.

  1. FTP (File Transfer Protocol):
    • Purpose: Used for transferring files between a client (your computer) and a server.
    • Example: Web developers use FTP to upload files (like HTML, CSS) to their website hosting server.
    • Visible in Browser? Sometimes. If you access an FTP server through a browser, you’ll see URLs like ftp://example.com.

  1. WS/WSS (WebSocket / Secure WebSocket):
    • Purpose: Used for real-time, two-way communication between a browser and a server.
    • Use Cases: Chat apps, live notifications, multiplayer games, stock price updates.
    • How It Works: A WebSocket connection starts as an HTTP/HTTPS request, then gets upgraded to a persistent connection using 101 Switching Protocols. Once established:
      • WS (ws://): Unsecured WebSocket connection.
      • WSS (wss://): Secured WebSocket connection (encrypted, like HTTPS).
    • Visible in Browser?
      • Not in the URL bar, but you can see WebSocket activity in Chrome DevTools under the "WS" filter in the Network tab.
      • You can inspect real-time frames (messages) exchanged between the client and the server.

Protocols and Browser Behavior

  1. Protocols That Appear in the Browser’s URL Bar:

    • http:// → Non-secure website.
    • https:// → Secure website.
    • ftp:// → File transfer (sometimes supported by browsers).
  2. Protocols That Don’t Appear in the URL Bar:

    • ws:// or wss:// → These are visible in DevTools during debugging, but they are used in the app’s JavaScript code (not typed into the address bar).
    • smtp:// and imap:// → Used for email communication but never appear in browsers. They’re handled by email clients like Gmail, Outlook, etc.

How Emails Work in the Browser (e.g., Gmail.com)

  • When you send an email from Gmail in your browser:
    • The browser communicates with Gmail's backend servers using HTTPS, not SMTP.
    • Gmail’s backend servers handle sending the email to the recipient using SMTP (this step is invisible to you).
  • What You See in Chrome DevTools:
    • You’ll see an HTTPS POST request in the Network tab when you click "Send." This request contains the email data (recipient, subject, body).
    • SMTP is used after this step between Gmail’s servers and the recipient’s mail server, but it’s not part of the browser’s activity.

WebSocket in Chrome DevTools

  • In modern browsers like Chrome, you can see WebSocket requests in DevTools:
    1. Open the Network Tab.
    2. Click on the "WS" filter to view WebSocket connections.
    3. Click a WebSocket request to inspect the frames (messages) being exchanged.

How TCP/IP Works in Real-Life Scenarios

Example 1: Loading a Website (HTTP/HTTPS)

  1. When you type https://example.com in your browser, the following happens:
    • Application Layer: Your browser creates an HTTP request.
    • TCP Layer: Breaks the HTTP request into packets.
    • IP Layer: Adds source and destination IP addresses and routes the packets to the server hosting example.com.
    • Destination Server: Reassembles packets, processes the request, and sends the webpage data back to you in the same way.
    • Your browser receives the packets, reassembles them, and renders the website.

Example 2: Sending an Email

  1. When you send an email using Gmail, the email is broken into packets.
  2. These packets are routed to Gmail’s servers via TCP/IP.
  3. Gmail’s servers then use SMTP (another protocol) to send the email to the recipient’s server.
  4. The recipient’s email client uses IMAP or POP3 (retrieval protocols) to fetch the email.

Example 3: Streaming a Video

  1. Services like Netflix or YouTube stream videos using TCP/IP. When you hit "Play":
    • Video data is broken into packets and transmitted using TCP.
    • Packets may arrive out of order but are reassembled correctly by TCP on your device.
    • This ensures smooth playback.

Email

NamasteDev-01-23-2025_01_22_PM

@yogain123
Copy link
Author

yogain123 commented Jan 25, 2025

CPU, OS, Kernal

  • The CPU executes machine code that is generated by a compiler or interpreter.
  • The OS provides an environment for software to run, managing resources like memory, storage, and hardware.
  • The Kernel is the core part of the OS that handles low-level tasks, ensuring that the software interacts efficiently with hardware and resources.

@yogain123
Copy link
Author

yogain123 commented Jan 25, 2025

CDN's

Uploading Images to a CDN: Key Points

1. Uploading to the CDN

  • Images are uploaded to the origin server of the CDN.
  • The origin server acts as the source of truth for the images.

2. CDN Distribution

  • Images are distributed to edge servers (located globally).
  • Edge servers cache images and serve them to users closer to their location, reducing latency.

3. CDN-Generated Links

  • A link is created (e.g., https://cdn-provider.com/image.jpg).
  • Your React app references this link to fetch the image directly from the nearest edge server.

4. Efficiency

  • Edge servers handle requests without always contacting the origin server (cache hits).
  • Origin server is accessed only on cache misses or when content is updated.

5. Storage Solutions

  • Use services like Amazon S3, Google Cloud Storage, or Azure Blob Storage.
  • These integrate with CDNs for scalable and efficient content delivery.

6. File Upload in Applications

  • Backend (e.g., Node.js):
    • Use AWS SDK to interact with S3.
    • Implement endpoints for file uploads.
  • Frontend (React):
    • Use FormData for multipart uploads (recommended for large files).
    • For small files, Base64 encoding is an option but increases file size by ~33%.

7. Multipart vs. Base64

  • Multipart (Preferred for large files): Efficient and sends binary data directly.
  • Base64 (For small files): Useful for quick previews but inflates file size.

Conclusion
For most scenarios, especially large files, use multipart uploads with CDN-backed storage solutions to ensure fast, efficient, and scalable image handling.


import React, { useState } from 'react';
import axios from 'axios';

const FileUpload = () => {
  const [file, setFile] = useState(null);

  const onFileChange = (e) => {
    setFile(e.target.files[0]);  // Get the selected file
  };

  const onFileUpload = () => {
    const formData = new FormData();
    formData.append('file', file);  // Append file to form data

    axios.post('http://localhost:3000/upload', formData)
      .then(response => {
        console.log('File uploaded successfully:', response);
      })
      .catch(error => {
        console.error('Error uploading file:', error);
      });
  };

  return (
    <div>
      <input type="file" onChange={onFileChange} />
      <button onClick={onFileUpload}>Upload</button>
    </div>
  );
};

export default FileUpload;

@yogain123
Copy link
Author

yogain123 commented Jan 25, 2025

Put, Patch, Post

POST:

  • Purpose: Create a new resource.
  • Idempotency: Non-idempotent (repeated requests create new resources each time).
  • Use Case: When submitting data to create a new entry (e.g., adding a new document).

PUT:

  • Purpose: Replace or update an existing resource (or create if it doesn’t exist).
  • Idempotency: Idempotent (same request gives the same result).
  • Use Case: When updating or replacing a full resource (e.g., replacing a document entirely).

PATCH:

  • Purpose: Partially update an existing resource.
  • Idempotency: Not necessarily idempotent (depends on the update).
  • Use Case: When updating only certain fields of a resource (e.g., updating one field in a document).

Using the correct HTTP methods (GET, POST, PUT, PATCH, DELETE) is important because:

  1. Clarity: Methods convey intent (e.g., GET for fetching, POST for creating, PUT/PATCH for updating, DELETE for deleting).
  2. Caching: GET can be cached, improving performance; POST cannot.
  3. Standards: RESTful APIs follow conventions, making them easier for developers and tools to understand and integrate.
  4. Idempotency: Methods like PUT and DELETE are idempotent, ensuring repeated requests have consistent results.
  5. Collaboration: Standard methods make APIs intuitive and reduce confusion for others working with them.

Using only POST with custom routes may work, but it breaks standards, reduces readability, and complicates integration with third-party tools or other developers.

@yogain123
Copy link
Author

yogain123 commented Jan 30, 2025

How OAuth Flow works

How OAuth Flow works - visual selection

1. Client Requests Authentication

  • The client (your app) makes a request to your Backend (or Backend for Frontend, BFF), asking to authenticate via Google OAuth.
  • The Backend responds with a redirect URL to Google's OAuth authorization endpoint (https://accounts.google.com/o/oauth2/v2/auth), including the following information:
    • client_id: Identifies the client (your app).
    • redirect_uri: The URL to which Google should redirect after authentication.
    • response_type: Typically "code", indicating you want an authorization code.
    • scope: Defines what level of access the client is requesting (e.g., email, profile).
    • state: A random string to prevent CSRF attacks (optional but recommended).

2. User Logs In to Google

  • The user is redirected to Google's login page (login.google.com) where they authenticate (log in) using their Google account.

3. Google Sends Authorization Code

  • After the user logs in and grants permission, Google will redirect the user back to your specified redirect_uri with an authorization code (auth_code), typically in the query string:
    https://yourapp.com/callback?code=AUTH_CODE&state=STATE
    
  • The authorization code is short-lived and can be exchanged for an access token.

4. Backend Exchanges Code for Access Token

  • The Backend (or BFF) receives the authorization code and sends it to Google's OAuth token endpoint (https://oauth2.googleapis.com/token) along with:
    • code: The authorization code received from Google.
    • client_id: Your app's client ID.
    • client_secret: Your app's client secret.
    • redirect_uri: Same redirect URI used in the initial request.
    • grant_type: "authorization_code", indicating the type of flow you're using.
  • Google will respond with an access token and, optionally, a refresh token:
    {
      "access_token": "ACCESS_TOKEN",
      "expires_in": 3600,
      "token_type": "Bearer",
      "refresh_token": "REFRESH_TOKEN"
    }

5. Backend Sends Access Token to Client

  • Once the Backend has the access token, it may choose to send it to the client (browser) either in the response header or in the URL as a query parameter.
  • Alternatively, the Backend could store the access token in a session (if using a server-side session management) or a cookie for easier client-side handling.

6. Client Sends Access Token for Subsequent Requests

  • For every subsequent request to the Backend, the client includes the access token (in the Authorization header as Bearer ACCESS_TOKEN).
  • The Backend verifies the token with Google (if needed) to check its authenticity, expiry, etc.

7. Handling Sessions (Optional)

  • Instead of passing the access token directly in the browser requests, the Backend might create a session:
    • If the Backend chooses to create a session, it can store the access token in a server-side session or cache (like Redis) and generate a session ID.
    • The session ID is sent to the client in a cookie.
    • The client includes the session ID with every request, allowing the Backend to validate the session against its session store.
  • The session is valid until the session expires, or the user logs out.

8. Token Validation

  • Every time the client makes a request with an access token, the Backend verifies its authenticity:
    • It can either validate the token directly by checking its validity and expiration, and most of this token are JWT
    • Or, if using a session ID, it checks the session store to ensure the session is still active.

9. Token Expiry and Refresh

  • Access tokens typically have a limited lifespan (e.g., one hour).
  • If the token expires, the refresh token (if provided) can be used to request a new access token from Google without requiring the user to log in again.
  • The client can send the refresh token to the Backend, which in turn exchanges it with Google for a new access token and possibly a new refresh token.

10. Logout

  • To log the user out, the Backend can invalidate the session (e.g., by removing the session ID or access token).
  • The client can also be instructed to clear the session/cookie.

Cookies: Automatically sent by the browser and extracted by the backend. , no need to add Bearer
Authorization header: Requires you to manually set the header with Bearer for each request.

Bearer means whoever possesses the token is authorized to access the resource.

Code Example

https://github.com/yogain123/GoogleOAuth


Screenshot 2025-05-19 at 11 52 32 AM

@yogain123
Copy link
Author

yogain123 commented Feb 9, 2025

IP address

1. IP Address vs. Router IP Address

When you connect to a Wi-Fi network, your device (laptop/phone) gets an IP address from the router. But there are two types of IP addresses to understand:

  • Your device gets a private IP (192.168.1.6 in your case) from the router.
  • Your router has a private IP (192.168.1.254 in your case) to talk to all devices inside the home.
  • Your router also has a public IP (like 103.42.58.123), which is used to communicate on the internet.

🚀 The router acts like a middleman:

  • Inside your home, devices use private IPs to communicate.
  • When a device wants to go online, the router replaces the private IP with its public IP (using NAT - Network Address Translation).

2. Does My IP Address Change When I Connect to a Different Router?

Yes! Your private IP changes when you connect to a different router because:

  • Each router has its own pool of IP addresses.
  • When you join a new Wi-Fi, that router assigns you a new private IP.

🔹 Example: Moving Between Networks

Location Router IP Your Device's IP
Home Wi-Fi 192.168.1.254 192.168.1.6
Office Wi-Fi 192.168.0.1 192.168.0.15
Coffee Shop Wi-Fi 10.0.0.1 10.0.0.8

🚀 Your device’s IP depends on the router you are connected to!

However, your public IP (assigned by your ISP) stays **mostly


Yes! The MAC address is the unique identifier for each device. Unlike an IP address, which can change, the MAC (Media Access Control) address is permanent and unique to each device’s network adapter (Wi-Fi or Ethernet).


1. What is a MAC Address?

  • A MAC address is a hardware address that is burned into your device's network card.
  • It looks something like this:
    00:1A:2B:3C:4D:5E (12 characters, hexadecimal format)
  • Every device (laptop, phone, smart TV) has a unique MAC address.

📌 Think of MAC addresses as serial numbers for network devices. They are always unique and do not change.


2. How is MAC Different from IP?

Feature MAC Address IP Address
Type Hardware (Physical) Software (Logical)
Uniqueness Globally unique Can change (assigned by router)
Example 00:1A:2B:3C:4D:5E 192.168.1.6
Assigned By Manufacturer Router (via DHCP)
Changes? No, fixed for device Yes, changes with networks
Scope Works within the local network Can be used globally (internet)

3. What is the Role of MAC in Networking?

  • When a device joins a network, it announces its MAC address.
  • The router assigns an IP to the MAC address.
  • Inside the home network, data is sent using MAC addresses.
  • Outside (internet), data is sent using IP addresses.

📌 Example:

  • Your router has a MAC table linking IPs to MAC addresses:
    192.168.1.6 → MAC: 00:1A:2B:3C:4D:5E (Your laptop)
    192.168.1.10 → MAC: 00:1A:2B:AA:BB:CC (Your phone)
    
  • If your laptop wants to talk to your phone, it uses the MAC address for communication.

Final Answer:

Yes, MAC addresses are unique to each system.
IP addresses can change, but MAC addresses do not.
MAC addresses work inside local networks, while IPs are used for the internet.


What is "Subnet Mask" (255.255.255.0)?
A subnet mask helps define how many devices can exist in the same network.
In simple terms, 255.255.255.0 means all devices that have IPs starting with 192.168.1.X are part of the same home network.
Example:

If you have a laptop (192.168.1.6) and a phone (192.168.1.10), both can talk to each other directly because they are in the same subnet.
But if a device had an IP like 192.168.2.5, it would be in a different subnet and wouldn’t directly communicate.

@yogain123
Copy link
Author

Socket.io

Socket.io Events Overview

Server (Node.js)

  • Listens on: join_room, send_message
  • Emits: receive_message

Client (React/Frontend)

  • Listens on: receive_message
  • Emits: join_room, send_message

ReactJS

import { useEffect, useState } from "react";
import { io } from "socket.io-client";

const socket = io("http://localhost:5345"); // Connect to backend

function App() {
  const [room, setRoom] = useState("");
  const [message, setMessage] = useState("");

  useEffect(() => {
    return () => {
      socket.disconnect();
    };
  }, []);

  socket.on("receive_message", (data) => {
    console.log("recevied message", data);
  });

  // Join a room
  const joinRoom = () => {
    socket.emit("join_room", room);
  };

  // Send a message
  const sendMessage = () => {
    socket.emit("send_message", { room, message });
  };

  return (
    <div style={{ textAlign: "center", padding: "20px" }}>
      <h1>Chat App</h1>

      {/* Room Input */}
      <input
        type="text"
        placeholder="Enter Room ID"
        value={room}
        onChange={(e) => setRoom(e.target.value)}
        style={{ marginRight: "10px", padding: "5px" }}
      />
      <button onClick={joinRoom}>Join Room</button>

      {/* Message Input */}
      <input
        type="text"
        placeholder="Type a message..."
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        style={{ marginTop: "10px", marginRight: "10px", padding: "5px" }}
      />
      <button onClick={sendMessage}>Send</button>
    </div>
  );
}

export default App;

NodeJS

const express = require("express");
const cors = require("cors");
const http = require("http");
const app = express();
const { Server } = require("socket.io");
const server = http.createServer(app); // Create HTTP server

// Add mandatory middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Initial route
app.get("/", (req, res) => {
  res.send(`<h1>Socket.IO Server Running</h1>`);
});

// Setup Socket.io server
const io = new Server(server, {
  cors: {
    origin: "http://localhost:3002", // Replace with your client's origin
    methods: ["GET", "POST"],
  },
});

io.on("connection", (socket) => {
  socket.on("join_room", (room) => {
    socket.join(room);
  });

  socket.on("send_message", (data) => {
    io.to(data.room).emit("receive_message", data);
  });

  socket.on("disconnect", () => {
    console.log("User disconnected:", socket.id);
  });
});

const PORT = 5345;
server.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}/`);
});

@yogain123
Copy link
Author

SMTP and IMAP for Email sending and Receiving

Sending Emails Using Node.js

If you want to send an email using code, you can use the Nodemailer npm package.

Using Nodemailer (Fixed Sender Email)

Nodemailer sends emails using SMTP, but the sender email will always be the same. This is useful for sending emails from a company email.

require('dotenv').config();
const express = require('express');
const nodemailer = require('nodemailer');
const cors = require('cors');

const app = express();
app.use(express.json());
app.use(cors()); // Allow frontend requests

// Email sending endpoint
app.post('/send-email', async (req, res) => {
    const { to, subject, message } = req.body;

    try {
        let transporter = nodemailer.createTransport({
            service: 'gmail',
            auth: {
                user: process.env.EMAIL, // Your Gmail
                pass: process.env.PASSWORD // App password
            }
        });

        let info = await transporter.sendMail({
            from: process.env.EMAIL,
            to: to,
            subject: subject,
            text: message
        });

        res.status(200).json({ success: true, info });
    } catch (error) {
        res.status(500).json({ success: false, error: error.message });
    }
});

app.listen(5000, () => console.log('Server running on port 5000'));

Using SendGrid (User-Defined Sender Email)

If you want to allow users to send emails from their own email addresses, use the SendGrid npm package.

require('dotenv').config();
const express = require('express');
const cors = require('cors');
const sgMail = require('@sendgrid/mail');

const app = express();
app.use(express.json());
app.use(cors());

sgMail.setApiKey(process.env.SENDGRID_API_KEY);

app.post('/send-email', async (req, res) => {
    const { from, to, subject, message } = req.body;

    const msg = {
        to,
        from, // Now emails will be sent from the user’s own address
        subject,
        text: message
    };

    try {
        await sgMail.send(msg);
        res.status(200).json({ success: true, message: 'Email sent successfully!' });
    } catch (error) {
        res.status(500).json({ success: false, error: error.response.body });
    }
});

app.listen(5000, () => console.log('Server running on port 5000'));

How Emails Are Sent and Received

Sending Emails (SMTP with SendGrid/Nodemailer)

  1. User Action:
    • In the React app, the user fills out a form (with fields like "From", "To", "Subject", and "Message").
  2. Backend Process:
    • The data is sent to a Node.js backend, which uses either Nodemailer (SMTP) or SendGrid API to send the email.
  3. Delivery:
    • The recipient’s email provider (Gmail, Yahoo, etc.) receives the email and places it in their inbox.

Receiving Emails (IMAP)

  1. Email Storage:
    • When an email arrives, it’s stored on the recipient's email provider’s server (e.g., Gmail).
  2. Backend Fetch:
    • The Node.js backend connects to the email provider using IMAP to fetch emails from the inbox.
  3. Parsing & Display:
    • The fetched emails are parsed (using a tool like mailparser) and sent to the React frontend for display in an inbox view.

Overall Architecture

[SEND EMAIL]
React (User Form) → Node.js (SendGrid SMTP) → Recipient’s Inbox

[RECEIVE EMAIL]
Email Provider (Inbox) → Node.js (IMAP Fetch) → React (Inbox UI)

@yogain123
Copy link
Author

yogain123 commented Feb 9, 2025

Video Website

Uploading a Video from Frontend to Backend

  1. Frontend Upload (React)

    • Use FormData to send the video file to the backend.
  2. Backend Processing (Node.js + Multer + AWS S3)

    • The backend receives the file using multer (or a similar multipart handler).
    • The video is uploaded to an S3 bucket.
    • The S3 URL of the uploaded video is stored in the database.
  3. S3 Multipart Upload

    • Frontend multipart is just a single file with boundaries set.
    • S3 multipart upload chunks the file into smaller parts and uploads them separately, improving efficiency for large files.

Retrieving and Displaying the Video

  1. Fetching the Video

    • Retrieve the S3 URL from the database.
    • Use the <video> tag in the frontend to play the video.
  2. MP4 vs HLS Format

    • MP4 works fine for simple use cases.
    • HLS (HTTP Live Streaming) is a better approach:
      • Breaks video into .ts chunks and stores them in S3.
      • Streams video in chunks, making it more efficient for bad network conditions.
      • Supports adaptive streaming (adjusts quality dynamically: 1080p, 720p, 144p, etc.).

Simple Example

Frontend (React) - Uploading Video

const uploadVideo = async (file) => {
  const formData = new FormData();
  formData.append("video", file);

  const response = await fetch("http://localhost:5000/upload", {
    method: "POST",
    body: formData,
  });

  const data = await response.json();
  console.log("Uploaded Video URL:", data.url);
};

Backend (Node.js + Express + Multer)

const express = require("express");
const multer = require("multer");
const AWS = require("aws-sdk");

const app = express();
const upload = multer({ storage: multer.memoryStorage() });

const s3 = new AWS.S3({ region: "us-east-1" });

app.post("/upload", upload.single("video"), async (req, res) => {
  const params = {
    Bucket: "your-bucket-name",
    Key: `videos/${Date.now()}-${req.file.originalname}`,
    Body: req.file.buffer,
    ContentType: req.file.mimetype,
  };

  const uploadResult = await s3.upload(params).promise();
  res.json({ url: uploadResult.Location });
});

app.listen(5000, () => console.log("Server running on port 5000"));

Frontend (React) - Playing Video

<video controls>
  <source src="https://your-bucket.s3.amazonaws.com/video.mp4" type="video/mp4" />
</video>

@yogain123
Copy link
Author

yogain123 commented Feb 9, 2025

Server Send Event - SSE

Backend Code (server.js)

const express = require("express");
const cors = require("cors");

const app = express();
const PORT = 5000;

app.use(cors());

// SSE endpoint
app.get("/stocks", (req, res) => {
    res.setHeader("Content-Type", "text/event-stream");
    res.setHeader("Cache-Control", "no-cache");
    res.setHeader("Connection", "keep-alive");

    console.log("Client connected to SSE");

    // Send stock updates every second
    const sendStockUpdate = () => {
        const stockData = {
            symbol: "AAPL",
            price: (Math.random() * 1000).toFixed(2), // Random stock price
            timestamp: new Date().toLocaleTimeString(),
        };
        res.write(`data: ${JSON.stringify(stockData)}\n\n`);
    };

    const interval = setInterval(sendStockUpdate, 1000);

    // Handle client disconnect
    req.on("close", () => {
        console.log("Client disconnected");
        clearInterval(interval);
        res.end();
    });
});

app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);

Frontend Code (App.js)

import React, { useEffect, useState } from "react";

const App = () => {
    const [stock, setStock] = useState(null);

    useEffect(() => {
        const eventSource = new EventSource("http://localhost:5000/stocks");

        eventSource.onmessage = (event) => {
            const newStock = JSON.parse(event.data);
            setStock(newStock);
        };

        eventSource.onerror = () => {
            console.error("EventSource failed");
            eventSource.close();
        };

        return () => eventSource.close(); // Cleanup on unmount
    }, []);

    return (
        <div style={{ textAlign: "center", marginTop: "50px" }}>
            <h1>Live Stock Price</h1>
            {stock ? (
                <div>
                    <h2>{stock.symbol}</h2>
                    <h3>${stock.price}</h3>
                    <p>Updated at: {stock.timestamp}</p>
                </div>
            ) : (
                <p>Waiting for updates...</p>
            )}
        </div>
    );
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment