परिचय
इस पोस्ट में, हम Vercel Edge फंक्शन और Upstash Redis का उपयोग करके आपके Next.js एप्लिकेशन के लिए एक वेटिंग रूम बनाएंगे।
आप सोर्स कोड और डेमो ऐप देख सकते हैं।
वेटिंग रूम?
वेटिंग रूम तब उपयोगी होता है जब आप अपनी वेबसाइट पर सक्रिय आगंतुकों की संख्या को सीमित करना चाहते हैं ताकि आपके संसाधनों पर ओवरलोड न हो।
हमारे कार्यान्वयन में, आप अधिकतम सक्रिय आगंतुकों की संख्या सेट कर सकेंगे। ट्रैफिक को नियंत्रित करने के लिए दो पैरामीटर होंगे:
- अधिकतम वेबसाइट क्षमता: एक ही समय में वेबसाइट पर अधिकतम आगंतुकों की संख्या?
- अधिकतम सत्र टाइमआउट: अधिकतम सेकंड की संख्या जो एक आगंतुक निष्क्रिय रह सकता है
चरण 1: प्रोजेक्ट सेटअप
Next.js ऐप बनाएं:
npx create-next-app@latest --typescript
upstash-redis इंस्टॉल करें:
npm install @upstash/redis
चरण 2: कार्यान्वयन
Vercel Next.js मिडलवेयर के माध्यम से Edge फंक्शन का समर्थन करता है। तो हम pages/api/ के तहत _middleware.ts जोड़ेंगे। मिडलवेयर कोड /api पर किए गए सभी अनुरोधों को इंटरसेप्ट करता है। विभिन्न कॉन्फ़िगरेशन के लिए यहां देखें।
pages/api/_middleware.ts को नीचे दिए अनुसार अपडेट करें:
import { Redis } from "@upstash/redis";
import { NextFetchEvent, NextRequest, NextResponse } from "next/server";
const COOKIE_NAME_ID = "__waiting_room_id";
const COOKIE_NAME_TIME = "__waiting_room_last_update_time";
const UPSTASH_REDIS_REST_TOKEN = "REPLACE_HERE";
const UPSTASH_REDIS_REST_URL = "REPLACE_HERE";
const TOTAL_ACTIVE_USERS = 10;
const SESSION_DURATION_SECONDS = 30;
const redis = new Redis({
url: UPSTASH_REDIS_REST_URL,
token: UPSTASH_REDIS_REST_TOKEN,
});
export async function middleware(req: NextRequest, ev: NextFetchEvent) {
const cookies = req.cookies;
let userId;
if (cookies[COOKIE_NAME_ID] != null) {
userId = cookies[COOKIE_NAME_ID];
} else {
userId = makeid(8);
}
const size = await redis.dbsize();
console.log("current capacity:" + size);
// पर्याप्त क्षमता है
if (size < TOTAL_ACTIVE_USERS) {
return getDefaultResponse(req, userId);
} else {
// साइट क्षमता पूर्ण है
const user = await redis.get(userId);
if (user === "1") {
// उपयोगकर्ता के पास पहले से सक्रिय सत्र है
return getDefaultResponse(req, userId);
} else {
// क्षमता पूर्ण है इसलिए उपयोगकर्ता को वेटिंग रूम पर भेजा जाता है
return getWaitingRoomResponse();
}
}
}
function makeid(length: number) {
let result = "";
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
async function getDefaultResponse(request: NextRequest, userId: string) {
// नीचे अनकमेंट करें ताकि स्टैटिक HTML कंटेंट के साथ फ़ंक्शन का टेस्ट किया जा सके
let newResponse = new NextResponse(default_html);
newResponse.headers.set("content-type", "text/html;charset=UTF-8");
// const response = await fetch(request)
// const newResponse = new Response(response.body, response)
const cookies = request.cookies;
const now = Date.now();
let lastUpdate = cookies[COOKIE_NAME_TIME];
let lastUpdateTime = 0;
if (lastUpdate) lastUpdateTime = parseInt(lastUpdate);
const diff = now - lastUpdateTime;
const updateInterval = (SESSION_DURATION_SECONDS * 1000) / 2;
if (diff > updateInterval) {
await redis.setex(userId, SESSION_DURATION_SECONDS, "1");
newResponse.cookie(COOKIE_NAME_TIME, now.toString());
}
newResponse.cookie(COOKIE_NAME_ID, userId);
return newResponse;
}
async function getWaitingRoomResponse() {
const newResponse = new NextResponse(waiting_room_html);
newResponse.headers.set("content-type", "text/html;charset=UTF-8");
return newResponse;
}
const waiting_room_html = `
<title>Waiting Room</title>
<meta http-equiv='refresh' content='30' />
<style>*{box-sizing:border-box;margin:0;padding:0}body{line-height:1.4;font-size:1rem;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif;padding:2rem;display:grid;place-items:center;min-height:100vh}.container{width:100%;max-width:800px}p{margin-top:.5rem}</style>
<div class='container'>
<h1>
<div>You are now in line.</div>
<div>Thanks for your patience.</div>
</h1>
<p>We are experiencing a high volume of traffic. Please sit tight and we will let you in soon. </p>
<p><b>This page will automatically refresh, please do not close your browser.</b></p>
</div>
`;
const default_html = `
<title>Waiting Room Demo</title>
<style>*{box-sizing:border-box;margin:0;padding:0}body{line-height:1.4;font-size:1rem;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif;padding:2rem;display:grid;place-items:center;min-height:100vh}.container{width:100%;max-width:800px}p{margin-top:.5rem}</style>
<div class="container">
<h1>
<div>Waiting Room Demo</div>
</h1>
<p> Visit this site from a different browser, you will be forwarded to the waiting room when the capacity is full. </p>
<p> Check <a href='//github.com/upstash/redis-examples/tree/master/nextjs-waiting-room' style={"color": "blue"}>this project </a> to set up a waiting room for your website.</p>
</div>
`;
हम Upstash Redis का उपयोग सक्रिय उपयोगकर्ता सत्रों को रखने के लिए स्टेट स्टोर के रूप में करते हैं। इसके REST API के लिए धन्यवाद, upstash-redis Vercel Edge फंक्शन के साथ संगत है।
आपको Upstash कंसोल से एक ग्लोबल डेटाबेस बनाने की आवश्यकता है। कंसोल से REST टोकन और REST URL कॉपी और पेस्ट करें। Redis डेटाबेस खाली होना चाहिए और केवल इस एप्लिकेशन द्वारा उपयोग किया जाना चाहिए।
अपनी स्वयं की आवश्यकताओं के आधार पर TOTAL_ACTIVE_USERS और SESSION_DURATION_SECONDS भी सेट करें।
आप waiting_room_html को अपडेट करके वेटिंग रूम पेज को कस्टमाइज़ कर सकते हैं।
आप getDefaultResponse() मेथड को अपडेट करके NextResponse का उपयोग करके अपने स्वयं के पेज पर फॉरवर्ड कर सकते हैं।
चरण 3: चलाएं और डिप्लॉय करें
npm run dev द्वारा एप्लिकेशन को स्थानीय रूप से चलाएं। आप TOTAL_ACTIVE_USERS को 1 पर सेट करना चाह सकते हैं और अलग-अलग ब्राउज़र में पेज (https://localhost:3000/api/hello) खोलकर वेटिंग रूम को आसानी से टेस्ट कर सकते हैं।
आप अपने एप्लिकेशन को Vercel पर डिप्लॉय कर सकते हैं
vercel deploy –prod
Vercel _middleware.ts को एज स्थानों पर चलाएगा ताकि वैश्विक स्तर पर विलंबता को कम किया जा सके।
निष्कर्ष
यह ट्यूटोरियल दिखाता है कि Vercel और Upstash की बदौलत एज पर एक डायनामिक एप्लिकेशन बनाना कितना आसान है। अधिक उदाहरणों के लिए हमारे उदाहरण देखें।
ट्विटर या डिस्कॉर्ड पर आपकी प्रतिक्रिया की प्रतीक्षा कर रहे हैं।