Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Redis

रीयल-टाइम आपातकालीन प्रतिक्रिया प्रणाली:अपस्टैश, रेडिस और क्यूस्टैश का लाभ उठाना

<पी> आज के लेख में हम इस बारे में बात करने जा रहे हैं कि आप Redis का उपयोग करके किसी देश के आश्रय मानचित्र के बारे में जानकारी को सुरक्षित रूप से संग्रहीत और एक्सेस करने के लिए अपस्टैश का लाभ कैसे उठा सकते हैं, और QStash के माध्यम से वास्तविक समय में डेटाबेस को अपडेट कर सकते हैं।

परिचय

<पी> वर्तमान वैश्विक संदर्भ में, प्राकृतिक आपदाएँ और सैन्य खतरे अधिक से अधिक प्रचलित होते जा रहे हैं। इसी तरह सामाजिक सेवा क्षेत्र में डिजिटलीकरण की आवश्यकता है।

<पी> आपातकालीन प्रसारण प्रणालियों जैसे एम्बर अलर्ट से लेकर सीओवीआईडी-19 ट्रैकिंग ऐप्स और एसओएस सिस्टम तक, हमने किसी देश को प्रभावित करने वाले किसी भी प्रकार के खतरनाक परिदृश्य के जवाब में कई प्रकार की तकनीकों का उपयोग होते देखा है।

<पी> अब, हम इस पर एक नज़र डालने जा रहे हैं कि कैसे रेडिस और सर्वर रहित वर्कलोड एक वास्तविक समय आपातकालीन प्रतिक्रिया प्रणाली के निर्माण में महत्वपूर्ण भूमिका निभा सकते हैं जो नागरिकों को निकटतम बंकर खोजने में मदद करता है, साथ ही उन्हें उपलब्ध क्षमता, सुविधाओं (जैसे विकलांग व्यक्तियों की सुविधाएं) और संसाधनों (पानी, बिजली, चिकित्सा आदि) के बारे में भी सूचित करता है।

<पी> रीयल-टाइम आपातकालीन प्रतिक्रिया प्रणाली:अपस्टैश, रेडिस और क्यूस्टैश का लाभ उठाना प्रोजेक्ट Cloud4 के सौजन्य से

सर्वर रहित क्यों?

<पी> तथाकथित सर्वर रहित अवधारणा पिछले वर्षों से डेवलपर्स के बीच लोकप्रिय हो गई है। हमने ऐसे स्टार्टअप्स की संख्या में वृद्धि देखी है जो इस आर्किटेक्चर का पालन करना चुनते हैं और बड़े निगमों में इसे अपनाने में भी वृद्धि हुई है।

<पी> विशेष रूप से जब राज्य अभिनेताओं के बारे में बात की जाती है, तो तेजी से विकास का माहौल और ऑटो-प्रबंधित सेवाएं आपातकालीन प्रतिक्रिया प्रणालियों के निर्माण की जटिलता और ओवरहेड को काफी कम कर सकती हैं। हमें दो अन्य कारकों को भी ध्यान में रखना होगा:

  1. बजट :यदि कोई देश किसी उभरती आपदा से नहीं गुज़र रहा है, तो क्या निर्णय लेने वाली भूमिका में कोई भी व्यक्ति अप्रयुक्त गणना शक्ति के लिए भुगतान को मंजूरी देने में सक्षम होगा? मुझे ऐसा संदेह है.
  2. यातायात में बढ़ोतरी :कल्पना कीजिए कि एक अलार्म बजता है और लाखों लोग निकटतम आश्रय खोजने के लिए वेब प्लेटफ़ॉर्म तक पहुंचते हैं। आपकी REST API इस अचानक आरपीएस (अनुरोध-प्रति-सेकंड) वृद्धि को कैसे संभालेगी? आवश्यक रीयलटाइम घटकों के बारे में क्या?
<पी> इन सभी अलग-अलग सवालों का जवाब अपस्टैश और एबली जैसे वास्तविक सर्वर रहित प्लेटफार्मों का उपयोग करके दिया जा सकता है, जो भारी-भरकम सर्वर को पावर देते हैं जो ऑटो-स्केल करते हैं और केवल आपके द्वारा उपयोग किए जा रहे संसाधनों के लिए चार्ज करते हैं।

रेडिस क्यों?

<पी> हमारे प्रोजेक्ट की डेटा आवश्यकताओं में विभिन्न एल्गोरिथम ऑपरेशन शामिल हैं जिन्हें उच्चतम संभव गति से निष्पादित किया जाना चाहिए। आश्रय की जानकारी का प्रतिनिधित्व करने के लिए बुनियादी डेटा संरचनाओं से लेकर विभिन्न मानदंडों के आधार पर किसी स्थान पर उपलब्ध जानकारी को क्रमबद्ध करने का एक सरल तरीका, रेडिस हमें NoSQL डेटाबेस के लचीलेपन को बनाए रखने की अनुमति देता है, जबकि विकास को सरल बनाने और तेज करने के लिए विभिन्न कार्य भी प्रदान करता है।

QStash क्यों?

<पी> पारंपरिक संदेश कतारें आर्किटेक्ट इवेंट-संचालित सिस्टम के लिए एक ठोस तरीका प्रदान करती हैं, लेकिन एक चेतावनी है:उनमें से अधिकतर पूरी तरह से एएमपीक्यू जैसे स्टेटफुल प्रोटोकॉल पर निर्भर हैं, जिसका अर्थ है कि वे सर्वर रहित फ़ंक्शंस जैसे अल्पकालिक वातावरण में उपयोग करने के लिए तैयार नहीं हैं।

<पी> QStash HTTP का उपयोग करके अनुरोध करने की अनुमति देकर इस समस्या को हल करता है, स्टेटलेस प्रोटोकॉल आमतौर पर ऐसे वातावरण में उपयोग किया जाता है। इसे वेबहुक के साथ जोड़कर, हम डेटाबेस से डेटा को अपडेट करने और लाने के लिए रीयलटाइम पाइपलाइन बना सकते हैं।

आवश्यकताएँ

<पी> पी.एस. .:यदि आप केवल नमूने देखना चाहते हैं, तो आवश्यकताओं और सेटअप अनुभाग को छोड़ दें। वे यह दिखाने के लिए हैं कि हम क्या और कैसे उपयोग कर रहे हैं।

<पी> यदि आप स्वयं इस प्रकार की प्रणाली बनाना चाहते हैं, तो आपको निम्नलिखित की आवश्यकता होगी:

  • एक अपस्टैश खाता, जिससे आप एक Redis डेटाबेस बनाएंगे और QStash एंडपॉइंट या विषय का उपयोग करेंगे;
  • एक एबली खाता और एक वेबहुक एकीकरण सेट अप
  • एक Next.js प्रोजेक्ट;
  • यदि आप इंटरनेट पर उपलब्ध URL पर स्थानीय अनुरोधों को प्रॉक्सी करना चाहते हैं तो ngrok जैसी एक टनलिंग सेवा;
  • कोई भी पैकेज प्रबंधक जो अनुरोधित पुस्तकालयों का समर्थन करता है। यह आलेख npm का उपयोग करेगा, लेकिन यह अनिवार्य नहीं है।
<पी> ध्यान दें :यह आलेख हमारे एप्लिकेशन के आर्किटेक्चर के संदर्भ में उक्त प्रौद्योगिकियों के उपयोग को प्रदर्शित करने के लिए कुछ बुनियादी प्रमाण-अवधारणा नमूने प्रदान करेगा। दिया गया कोड उत्पादन के लिए तैयार नहीं है और बेहतर पढ़ने के लिए इसे सरल और छोटा किया गया है। यदि आप तैनाती (अपवाद प्रबंधन, सुरक्षा, आदि) करना चाहते हैं तो आवश्यक संशोधन करना सुनिश्चित करें

सेटअप

सर्वर रहित फ़ंक्शन

<पी> हम सर्वर रहित वर्कलोड को उपयोगकर्ता के स्थान के करीब चलाने के लिए Next.js के एज एपीआई मार्गों का उपयोग करने जा रहे हैं।

<पी> Next.js प्रोजेक्ट बनाने के लिए npx create-next-app@latest <your-app-name> चलाएँ मूल निर्देशिका में. उसके बाद आप npm run dev चला सकते हैं विकास सर्वर प्रारंभ करने के लिए, npm run build एक उत्पादन बंडल और npm run start बनाने के लिए उत्पादन सर्वर प्रारंभ करने के लिए.

<पी> Next.js एपीआई मार्गों के लिए नोड वातावरण को डिफ़ॉल्ट के रूप में उपयोग करता है। हम इसे दो तरीकों से बदल सकते हैं:

  1. प्रति-मार्ग दृष्टिकोण. निम्नलिखित निर्यात को वांछित मार्ग पर जोड़ें:
    export const config = {
     runtime: "experimental-edge",
    };
  2. वैश्विक दृष्टिकोण. बढ़त बनाना डिफ़ॉल्ट रनटाइम, अपनी अगली.config,js फ़ाइल में निम्नलिखित जोड़ें:
    const nextConfig = {
     // ...
     experimental: {
     runtime: "experimental-edge",
     },
     // ...
    };

अपस्टैश

<पी> अपस्टैश प्रदाता बनाने के लिए इस गाइड का पालन करें।

<पी> QStash-रिसीवर रूट सेटअप करने के लिए, इस गाइड का पालन करें। ध्यान दें कि Ably हमें वेबहुक संदेश एन्कोडिंग, JSON और MessagePack के लिए दो विकल्प प्रदान करता है। यदि आप पूर्व का उपयोग करना चाहते हैं, तो आपको संभावित एन्क्रिप्शन संगतता समस्याओं पर काम करने के लिए JWT के बजाय प्राधिकरण हेडर का उपयोग करने की आवश्यकता हो सकती है। सरलता के लिए हम JSON से जुड़े रहेंगे।

कुशल

<पी> रीयलटाइम कार्यक्षमता के लिए, हम एबली के प्रोटोकॉल का उपयोग करेंगे, जो जहां संभव हो वहां वेबसॉकेट पर डिफ़ॉल्ट होता है। आरंभ करने के लिए इस गाइड का पालन करें और, जैसा कि हम Next.js का उपयोग कर रहे हैं, आप @abable-labs/react-hooks npm पैकेज पर एक नज़र डाल सकते हैं।

<पी> हमें अपने QStash URL को इंगित करने और सभी आवश्यक हेडर जोड़ने के लिए एक वेबहुक एकीकरण भी स्थापित करना चाहिए।

<पी> यदि आप उत्पादन के लिए जा रहे हैं, तो प्रमाणीकरण और सुरक्षा की भी जांच करें।

वैकल्पिक:स्थानीय सुरंग बनाना

<पी> ngrok

के साथ शुरुआत करने के लिए इस गाइड का पालन करें

वास्तुकला

प्रवाह

<पी> हमारे एप्लिकेशन के प्रवाह को बेहतर ढंग से समझने के लिए, आइए इस आरेख को देखें (excalidraw.com के साथ बनाया गया):

<पी> रीयल-टाइम आपातकालीन प्रतिक्रिया प्रणाली:अपस्टैश, रेडिस और क्यूस्टैश का लाभ उठाना

<पी> जैसा कि आप देख सकते हैं हमने दो प्रकार के उपयोगकर्ताओं को परिभाषित किया है:

  1. नागरिक , जो किसी आश्रय या स्थान की जानकारी तक पहुंच सकता है, और बंकर में जाने के अपने इरादे की घोषणा कर सकता है
  2. व्यवस्थापक , जो बंकर के लॉजिस्टिक्स डेटा को संशोधित कर सकता है और उपलब्धता को संशोधित कर सकता है (उदाहरण के लिए, पुष्टि करें कि कोई व्यक्ति/परिवार स्थान पर पहुंच गया है)
<पी> हम फ्रंटएंड और बैकएंड को यथासंभव अलग रखते हुए डेटा को वास्तविक समय में उपलब्ध कराने का प्रयास कर रहे हैं, इसलिए हम क्लाइंट के साथ संचार करने के लिए एबली चैनल का उपयोग करेंगे और हर बार उपलब्धता में बदलाव होने पर एक वेबहुक ट्रिगर करेंगे।

<पी> साथ ही, हम बैकएंड से संदेशों को प्रकाशित करने के लिए एबली के REST API का उपयोग करेंगे, क्योंकि हमें किसी भी प्रकार के स्टेटफुल कनेक्शन का उपयोग नहीं करना चाहिए।

डेटा

<पी> वर्तमान में हमें दो मुख्य डेटा प्रकार संग्रहीत करने होंगे:

  • <पी> एक आश्रय की जानकारी, जो रेडिस हैश का रूप ले सकती है और इसमें निम्नलिखित गुण हैं:

    • कुंजी का नाम country-city-number (उदा:RO-CJ-01 )
    • उपलब्धता (उदा:300 )
    • विशेषताएं (उदा:["disabled persons special acces", "counseling"] )
    • संसाधन:
      {
       resource: quantity,
       or
       resource: list
       ...
      }
      उदाहरण:
      {
       "water": "200 liters",
       "medicine": ["insuline", ...]
      }
    • बिजली:yes/no
    • हीटिंग:yes/no
    • स्थिति:[longitude, latitude] या
      {
       longitude: number,
       latitude: number
      }
    • _id:हम इसे यादृच्छिक रूप से उत्पन्न करेंगे
  • <पी> किसी स्थान की जानकारी

    <पी> जबकि हम कर सकते हैं निर्दिष्ट स्थान के लिए उपलब्ध आश्रयों को खोजने के लिए एक नेस्टेड क्वेरी करें, क्वेरी को सरल और अनुकूलित करने के लिए उन्हें एक अलग डेटा संरचना के रूप में संग्रहीत करना एक बेहतर विचार हो सकता है। ऐसा करने के लिए, हम रेडिस सेट का उपयोग कर सकते हैं और तत्वों को <geographical-unit>-<name> नाम दे सकते हैं (उदा:country-RO या city-CJ ). इस तरह हम नकल को भी रोक रहे हैं

    <पी> उदा:

     city-CJ : ["RO-CJ-01", "RO-CJ-02", "RO-CJ-03"]
<पी> लेकिन अभी भी एक समस्या बनी हुई है:हम किसी नागरिक के आश्रय में जाने के इरादे और वास्तविक इरादे के बीच अंतर कैसे कर सकते हैं? आश्रय के व्यवस्थापक की पुष्टि से शुरू हुई अधिभोग का अद्यतन? हम ऐसा दो तरीकों से कर सकते हैं:

  1. <पी> लगातार अपडेट करें आश्रय की उपलब्धता कुंजी:एक उपयोगकर्ता आने के अपने इरादे की घोषणा करता है (अकेले या परिवार के साथ/आदि) => हम x से वृद्धि करते हैं; व्यवस्थापक को पता चलता है कि पुष्टि मान्य नहीं है => हम x से कमी करते हैं (या -x द्वारा वृद्धि)

    <पी> यहां समस्या यह है कि व्यवस्थापक को सत्य के स्रोत के रूप में कार्य करना चाहिए और नागरिक के स्थान पर नज़र रखनी चाहिए; इसके अलावा, आश्रय के डेटा पर तुरंत भरोसा नहीं किया जा सकता

  2. <पी> एक अलग स्ट्रिंग कुंजी बनाएं shelter-"availability" नाम दिया गया है (उदा:RO-CJ-01-availability ) और रियलटाइम-अपडेटेड वैल्यू को स्टोर करें। इस तरह हम रियलटाइम अपडेट कर सकते हैं, और अपनी हैश की उपलब्धता कुंजी को सत्य के स्रोत के रूप में रख सकते हैं।

    <पी> ध्यान दें कि क्लाइंट पक्ष पर हम हैश और स्ट्रिंग कुंजी दोनों लाएंगे, और उन्हें वास्तविक उपलब्धता और अनुमानित उपलब्धता के रूप में प्रस्तुत करेंगे। एक वैकल्पिक दृष्टिकोण यह होगा कि केवल स्ट्रिंग को लाया जाए और आवश्यकता पड़ने पर सत्य के स्रोत पर वापस लौटाया जाए। हालाँकि इससे नेटवर्क लोड कम हो जाएगा, व्यवस्थापक को डेटा को लगातार सत्यापित करने की आवश्यकता होगी (जैसा कि पहले परिदृश्य में) और, वास्तव में कम प्राप्त करें, हमें आश्रय की उपलब्धता कुंजी को अलग से संग्रहीत करने की आवश्यकता होगी (याद रखें, हमें अभी भी अन्य जानकारी प्राप्त करने की आवश्यकता है!)।

सॉर्टिंग

<पी> आइए एक अन्य रेडिस डेटा प्रकार का लाभ उठाएं जिसे सॉर्टेड सेट कहा जाता है। मान लें कि हम किसी स्थान पर बंकरों को उपलब्धता, सुविधाओं या उपलब्ध संसाधनों के आधार पर क्रमबद्ध करना चाहते हैं:जैसा कि मैंने पहले उल्लेख किया है, हम एक नेस्टेड क्वेरी कर सकते हैं लेकिन समय की कीमत पर और बहुत बड़े डेटा लोड के साथ। एक बेहतर समाधान प्रत्येक फ़िल्टरिंग मानदंड के लिए क्रमबद्ध सेट बनाना होगा (हम उन्हें <geographical-unit>-<name>-<criteria> नाम दे सकते हैं) , जैसे city-CJ-availability या country-RO-food )

<पी> उदाहरण:city-B-availability स्कोर सामग्री 200आरओ-बी-02100आरओ-बी-01 <पी> इस उदाहरण में, उपलब्धता स्कोर की गणना total seats - current occupation के रूप में की गई थी .

उदाहरण

<पी> हम अपने एपीआई और क्लाइंट के व्यवहार को प्रदर्शित करने के लिए कुछ बुनियादी कोड लिख सकते हैं

अंतिमबिंदु

<पी> मुख्य रूप से, हमें इसकी आवश्यकता है:

  • एक डेटा एंडपॉइंट जो क्लाइंट को किसी भी अनुरोधित जानकारी प्रदान करेगा
  • हमारे डेटा प्रकारों को बनाने या अपडेट करने के लिए एक एडपॉइंट

ग्राहक

<पी> उपयोगकर्ता के स्थान को ट्रैक करने के बाद हम स्वचालित रूप से "उपलब्धता" चैनल से जुड़ जाएंगे और यदि नागरिक बंकर में जाने का इरादा रखता है तो एक संदेश प्रकाशित करेंगे।

<पी> सबसे पहले, आइए /_app.js से एक कनेक्शन बनाएं फ़ाइल:

import { useEffect, useState } from "react";
 
import "../styles/globals.css";
 
import { configureAbly } from "@ably-labs/react-hooks";
 
export default function App({ Component, pageProps }) {
 const [loaded, setLoaded] = useState(false);
 useEffect(() => {
 configureAbly({
 // In a production system, you should use authentication
 key: process.env.NEXT_PUBLIC_ABLY_API_KEY,
 });
 setLoaded(true);
 }, []);
 
 if (!loaded) return <div>loading...</div>;
 return <Component {...pageProps} />;
}
<पी> और फिर किसी भी घटक में चैनल से कनेक्ट करें जिसकी हमें आवश्यकता है:

import { useChannel } from "@ably-labs/react-hooks";
 
export default function Test() {
 const [availability] = useChannel("availability", (msg) => {
 console.log(msg);
 });
 
 return <></>;
}

डेटाबेस के साथ कार्य करना

नया डेटा जोड़ना

<पी> Redis में नया डेटा जोड़ने के लिए हम HSET, SET और SADD कमांड

का उपयोग कर सकते हैं
export default async (req) => {
 let data = await req.json();
 
 if (data.type === "shelter") {
 // Remove the 'type' key as it is not neccesary anymore
 delete data.type;
 const { name: shelter, availability } = data;
 
 let shelterData = data;
 // Generate a random id.
 shelterData._id = Math.random()
 .toString(36)
 .replace(/[^a-z]+/g, "")
 .substring(0, 7);
 
 // Store the shelter's info as a hash
 await redis.hset(shelter, shelterData);
 
 // Store the realtime-updated availability as a string
 await redis.set(shelter + "-availability", availability);
 return new Response("ok");
 } else if (data.type === "location") {
 const { name: location, shelters } = data;
 
 await redis.sadd(location, ...shelters);
 
 return new Response("ok");
 }
};

मौजूदा डेटा अपडेट कर रहा है

<पी> बुनियादी यूडी (अपडेट-डिलीट) संचालन के अलावा, हम आश्रयों की उपलब्धता को संशोधित करने के लिए रेडिस आईएनसीआरबीवाई और एचआईएनसीआरबीवाई कमांड का उपयोग कर सकते हैं। <पी> यदि कोई नागरिक बंकर में जाने के अपने इरादे की घोषणा करता है, तो हम क्लाइंट ऐप

से एक संदेश प्रकाशित कर सकते हैं
availability.publish("update", {
 shelter: "RO-CJ-01",
 availability: 1, // Or -x, if the user cancels.
});
<पी> जैसा कि आर्किटेक्चर में बताया गया है, यह एक वेबहुक ट्रिगर करेगा जिससे हम डेटा ले सकते हैं और shelter-"availability" को अपडेट कर सकते हैं। कुंजी.

await redis.incrby(shelter + "-availability", value);
<पी> यदि आप सर्वर से अपडेट कर रहे हैं (उदाहरण:व्यवस्थापक पुष्टिकरण), तो इसके बजाय REST API का उपयोग करना न भूलें।

डेटा पुनर्प्राप्त करना

<पी> सर्वर पर, हम GET, SMEMBERS और HGETALL कमांड का उपयोग कर सकते हैं।

<पी> क्लाइंट पर, हम चैनल में संदेशों को सुन सकते हैं और तदनुसार स्थिति को अपडेट कर सकते हैं।

संक्षेप में कहें तो

<पी> आज हमने इस पर एक नज़र डाली कि हम वास्तविक दुनिया का आपातकालीन ट्रैकिंग ऐप बनाने के लिए एक शक्तिशाली सर्वर रहित आर्किटेक्चर का लाभ कैसे उठा सकते हैं। हालांकि इसे पूरा करने के लिए कई दृष्टिकोण हैं, मैं व्यक्तिगत रूप से सरलीकृत डेवलपर अनुभव के कारण इस तरह के प्रवाह के साथ जाने की सलाह देता हूं।

<पी> हो सकता है कि आप एक वरिष्ठ डेवलपर हों जो वितरित कंप्यूटिंग सिस्टम बनाने के आदी हों और एक प्रबंधित सेवा की आवश्यकता महसूस करते हों। या, आप एक नौसिखिया हो सकते हैं लेकिन आपके पास एक ऐसा विचार है जो संभावित रूप से दुनिया को अच्छे के लिए बदल सकता है। सही उपकरण ढूंढना हमेशा प्रक्रिया का एक अनिवार्य हिस्सा होता है।

<पी> मुझे बताएं कि आप इस लेख के बारे में क्या सोचते हैं, और यदि आपका कोई प्रश्न है तो बेझिझक मुझे लिंक्डइन पर संदेश भेजें या जीथब पर मेरे अन्य कोड देखें।


  1. जाँच करें कि दिया गया ट्री ग्राफ C++ में रैखिक है या नहीं जाँच करें कि दिया गया ट्री ग्राफ C++ में रैखिक है या नहीं

    यहां हम देखेंगे कि कैसे जांचा जाता है कि एक ट्री ग्राफ रैखिक है या नहीं। एक रैखिक वृक्ष ग्राफ को एक पंक्ति में व्यक्त किया जा सकता है, मान लीजिए कि यह एक रैखिक वृक्ष ग्राफ का एक उदाहरण है। लेकिन यह रैखिक नहीं है - यह जांचने के लिए कि ग्राफ रैखिक है या नहीं, हम दो शर्तों का पालन कर सकते हैं यद

  1. सी ++ प्रोग्राम लिंक्ड लिस्ट का उपयोग करके ग्राफ का प्रतिनिधित्व करने के लिए सी ++ प्रोग्राम लिंक्ड लिस्ट का उपयोग करके ग्राफ का प्रतिनिधित्व करने के लिए

    एक ग्राफ की घटना मैट्रिक्स स्मृति में संग्रहीत करने के लिए एक ग्राफ का एक और प्रतिनिधित्व है। यह मैट्रिक्स एक वर्ग मैट्रिक्स नहीं है। आपतन मैट्रिक्स का क्रम V x E है। जहाँ V शीर्षों की संख्या है और E ग्राफ़ में किनारों की संख्या है। इस मैट्रिक्स की प्रत्येक पंक्ति में हम कोने रख रहे हैं, और प्रत्ये

  1. जावास्क्रिप्ट में String.trimStart () और String.trimEnd () विधियों की व्याख्या करें जावास्क्रिप्ट में String.trimStart () और String.trimEnd () विधियों की व्याख्या करें

    String.trimStart() मेथड का इस्तेमाल स्ट्रिंग की शुरुआत से व्हाइटस्पेस को हटाने के लिए किया जाता है जबकि String.trimEnd() मेथड स्ट्रिंग के अंत से व्हाइटस्पेस को हटाता है। String.trimStart() और String.trimEnd() विधियों के लिए कोड निम्नलिखित है - उदाहरण <!DOCTYPE html> <html lang="en&quo