কম্পিউটার টিউটোরিয়াল

Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ রিয়েল-টাইম বিজ্ঞপ্তি:একটি ধাপে ধাপে নির্দেশিকা

এই পোস্টে, আমি কিভাবে Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ সার্ভার-প্রেরিত ইভেন্ট ব্যবহার করে রিয়েল টাইম নোটিফিকেশন তৈরি করেছি সে সম্পর্কে কথা বলি। Upstash Redis-এ মেসেজ চ্যানেলগুলিকে কাজে লাগানো আপনার অ্যাপ্লিকেশনগুলির যোগাযোগের স্থাপত্যকে উল্লেখযোগ্যভাবে উন্নত করতে পারে, তাদের আরও প্রতিক্রিয়াশীল এবং গতিশীল করে তোলে৷

ডেমো

আমরা কি ব্যবহার করব

  • Next.js (ফ্রন্ট-এন্ড এবং ব্যাক-এন্ড)
  • Upstash Redis (সার্ভার-প্রেরিত ইভেন্ট প্রকাশ করার আদেশ সহ)
  • Tailwind CSS (স্টাইলিং)
  • ভার্সেল (নিয়োজন)

আপনার যা প্রয়োজন

  • Node.js 18
  • একটি Upstash অ্যাকাউন্ট
  • একটি Vercel অ্যাকাউন্ট

Upstash Redis সেট আপ করা হচ্ছে

একবার আপনি একটি Upstash অ্যাকাউন্ট তৈরি করেছেন এবং লগ ইন করলে আপনি Redis ট্যাবে যান এবং একটি ডাটাবেস তৈরি করতে যাচ্ছেন৷

Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ রিয়েল-টাইম বিজ্ঞপ্তি:একটি ধাপে ধাপে নির্দেশিকা

Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ রিয়েল-টাইম বিজ্ঞপ্তি:একটি ধাপে ধাপে নির্দেশিকা

আপনি আপনার ডাটাবেস তৈরি করার পরে, আপনি তারপরে বিশদ ট্যাবে যাচ্ছেন। আপনি আপনার ডাটাবেস সংযোগ বিভাগটি খুঁজে না পাওয়া পর্যন্ত নিচে স্ক্রোল করুন। Redis URL অনুলিপি করুন এবং এটি নিরাপদ কোথাও সংরক্ষণ করুন, আমরা এটি UPSTASH_REDIS_URL হিসাবে ব্যবহার করব আমাদের পরিবেশ পরিবর্তনশীল হিসাবে।

Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ রিয়েল-টাইম বিজ্ঞপ্তি:একটি ধাপে ধাপে নির্দেশিকা

এছাড়াও, আপনি REST API বিভাগটি খুঁজে না পাওয়া পর্যন্ত নিচে স্ক্রোল করুন এবং .env নির্বাচন করুন বোতাম বিষয়বস্তু অনুলিপি করুন এবং নিরাপদ কোথাও সংরক্ষণ করুন, আমরা UPSTASH_REDIS_REST_URL হিসাবে প্রাপ্ত ভেরিয়েবলগুলি ব্যবহার করব এবং UPSTASH_REDIS_REST_TOKEN .

Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ রিয়েল-টাইম বিজ্ঞপ্তি:একটি ধাপে ধাপে নির্দেশিকা

প্রকল্প সেট আপ করা হচ্ছে

সেট আপ করতে, শুধু অ্যাপ রেপো ক্লোন করুন এবং এতে যা আছে তা শিখতে এই টিউটোরিয়ালটি অনুসরণ করুন। প্রকল্পটি ফর্ক করতে, চালান:

git clone https://github.com/rishi-raj-jain/upstash-nextjs-publish-messages-with-sse-example
cd upstash-nextjs-publish-messages-with-sse-example
npm install

একবার আপনি রেপো ক্লোন করার পরে, আপনি একটি .env ফাইল তৈরি করতে যাচ্ছেন। আপনি উপরের বিভাগগুলি থেকে আমরা যে আইটেমগুলি সংরক্ষণ করেছি তা যোগ করতে চলেছেন৷

এটি দেখতে এইরকম কিছু হওয়া উচিত:

# .env
 
# Obtained from the steps as above
 
# Upstash Redis Secrets
UPSTASH_REDIS_URL="rediss://default:...@...-...-...-....upstash.io:..."
UPSTASH_REDIS_REST_URL="https://...-...-...-....upstash.io"
UPSTASH_REDIS_REST_TOKEN="...="

কিভাবে UPSTASH_REDIS_URL এ নোট করুন ভেরিয়েবল বলে "রিডিস" এবং "রিডিস" নয়, এটি টিএলএস/এসএসএল বিকল্প ব্যবহার করার জন্য।

এই পদক্ষেপগুলির পরে, আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করে স্থানীয় পরিবেশ শুরু করতে সক্ষম হবেন:

npm run dev

রিপোজিটরি স্ট্রাকচার

এটি প্রকল্পের মূল ফোল্ডার কাঠামো। আমি লাল রঙে চিহ্নিত করেছি যে ফাইলগুলি এই পোস্টে আরও আলোচনা করা হবে যা নিম্নলিখিতগুলির সাথে সম্পর্কিত:

  • Upstash Redis-এ বার্তা চ্যানেল বোঝা
  • Next.js অ্যাপ রাউটারে সার্ভার-প্রেরিত ইভেন্ট API তৈরি করা হচ্ছে
  • বিজ্ঞপ্তি প্রকাশ করতে Upstash Redis এর সাথে Next.js সার্ভার অ্যাকশন সেটআপ করুন
  • রিয়েল-টাইমে অবিরামভাবে শোনা এবং বিজ্ঞপ্তিগুলি প্রদর্শন করতে Next.js ফ্রন্টএন্ড সেটআপ করুন

Upstash Redis, Next.js সার্ভার অ্যাকশন এবং Vercel সহ রিয়েল-টাইম বিজ্ঞপ্তি:একটি ধাপে ধাপে নির্দেশিকা

Upstash Redis-এ মেসেজ চ্যানেল বোঝা

Upstash Redis-এ, প্রকাশ/সাবস্ক্রাইব মডেলটি বার্তা চ্যানেলের মূলে রয়েছে। প্রকাশকরা নামযুক্ত চ্যানেলগুলিতে বার্তা সম্প্রচার করে এবং গ্রাহকরা রিয়েল-টাইমে নির্দিষ্ট চ্যানেলগুলি থেকে বার্তাগুলি গ্রহণ করতে সক্ষম হন। এই মডেলটি একটি অ্যাপ্লিকেশনের বিভিন্ন অংশের মধ্যে বিরামহীন যোগাযোগ সক্ষম করে৷

এজ সামঞ্জস্যপূর্ণ লাইব্রেরি, @upstash/redis ব্যবহার করে একটি চ্যানেলে বার্তাগুলি কীভাবে প্রকাশ করা যেতে পারে তা এখানে রয়েছে 👇🏻

import { Redis } from '@upstash/redis'
 
// Connect to an Upstash Redis instance
const redis = Redis.fromEnv()
 
// Publish a message to the Upstash Redis instance
await redis.publish('posts', JSON.stringify({ date: new Date().toString(), message: "I am a new message." }))

সাবস্ক্রাইবাররা কীভাবে একটি Upstash Redis চ্যানেল শুনতে পারে তা এখানে রয়েছে (এখানে, posts ) নোড সামঞ্জস্যপূর্ণ লাইব্রেরির সাথে, ioredis 👇🏻

// Use ioredis to be able to subscribe to an Upstash Redis instance
import Redis from 'ioredis'
 
// Create an Upstash Redis Subscriber instance
const redisSubscriber = new Redis(process.env.UPSTASH_REDIS_URL)
 
// Define the key to listen and publish messages to
const setKey = 'posts'
 
// Subscribe to Redis updates for the key: "posts"
// In case of any error, just log it
redisSubscriber.subscribe(setKey, (err) => {
 if (err) console.log(err)
})
 
// Listen for new posts from Redis
redisSubscriber.on('message', (channel, message) => {
 // Log the data when the channel message is received is same as the message is published to
 if (channel === setKey) console.log(mesage)
})

একটি চ্যানেলে একটি বার্তা প্রকাশ করার পরে, সমস্ত গ্রাহকরা তাত্ক্ষণিকভাবে বার্তাটি গ্রহণ করে, যা Upstash Redis-এর মধ্যে দক্ষ এবং রিয়েল-টাইম যোগাযোগের অনুমতি দেয়৷

Next.js অ্যাপ রাউটারে সার্ভার-প্রেরিত ইভেন্ট API তৈরি করা হচ্ছে

সার্ভার-প্রেরিত ইভেন্টগুলি একাধিক ক্লায়েন্ট অনুরোধের প্রয়োজন ছাড়াই রিয়েল টাইমে নতুন ডেটা পাঠানোর একটি শক্তিশালী উপায়। প্রথাগত অনুরোধ-প্রতিক্রিয়া পদ্ধতির বিপরীতে, SSE সার্ভার থেকে ক্লায়েন্টের কাছে একক, দীর্ঘস্থায়ী HTTP সংযোগের মাধ্যমে ডেটার একমুখী প্রবাহ সক্ষম করে।

Next.js অ্যাপ রাউটারে আপনি কীভাবে সার্ভার-প্রেরিত ইভেন্টগুলি বাস্তবায়ন করতে পারেন তা এখানে রয়েছে 👇🏻

// File: app/api/stream/route.js
 
// Prevents this route's response from being cached on Vercel
export const dynamic = 'force-dynamic'
 
export async function GET() {
 const encoder = new TextEncoder()
 // Create a streaming response
 const customReadable = new ReadableStream({
 start(controller) {
 const message = 'Hey, I am a message.'
 controller.enqueue(encoder.encode(`data: ${message}\n\n`))
 },
 })
 // Return the stream response and keep the connection alive
 return new Response(customReadable, {
 // Set the headers for Server-Sent Events (SSE)
 headers: {
 'Content-Type': 'text/event-stream; charset=utf-8',
 Connection: 'keep-alive',
 'Cache-Control': 'no-cache, no-transform',
 'Content-Encoding': 'none'
 },
 })
}

Next.js সার্ভার অ্যাকশন ব্যবহার করে Upstash Redis-এ বার্তা প্রকাশ করা

Next.js সার্ভার অ্যাকশন আপনাকে Next.js-এ আপনার ফ্রন্টএন্ড কোডের মধ্যে সরাসরি সার্ভার-সাইড লজিক সংজ্ঞায়িত করতে দেয়। এটি ম্যানুয়ালি API রুট তৈরির প্রক্রিয়া এবং ফর্ম জমা দেওয়ার স্থিতি(গুলি) জমা দেওয়ার এবং ট্র্যাক করার ঝামেলা সংরক্ষণ করে৷

use server সহ ফাংশনের শীর্ষে, আমরা নিশ্চিত করতে পারি যে ফাংশনগুলি শুধুমাত্র সার্ভার-সাইডে চলে। আমাদের ফর্ম জমা সার্ভার অ্যাকশনের ভিতরে, আমরা message বের করি ফর্ম থেকে মান, ব্যবহারকারীর দেশ পেতে Vercel হেডার ব্যবহার করুন এবং posts-এ একটি বার্তা হিসাবে তথ্য প্রকাশ করুন Upstash Redis বার্তা চ্যানেল।

// File: app/actions.jsx
 
'use server'
 
import { Redis } from '@upstash/redis'
import { headers } from 'next/headers'
 
// The function that takes care of obtaining the country code from Vercel headers
// And publishing messages to the Upstash Redis database with the current timestamp
export async function publishNotification(formData) {
 'use server'
 const redis = Redis.fromEnv()
 
 // Extract the message in the form submitted
 const message = formData.get('message')
 
 // Obtain country of the user using Vercel's x-vercel-ip-country header
 const headersList = headers()
 const country = headersList.get('x-vercel-ip-country')
 
 // Publish the message to the "posts" channel in Upstash Redis
 await redis.publish(
 'posts',
 JSON.stringify({
 message,
 country,
 date: new Date().toString(),
 }))
}

ফর্মটি জমা দেওয়ার সাথে সাথে এই সার্ভার অ্যাকশনটি চালু করতে, আমরা এটিকে হ্যান্ডলার হিসাবে ফর্ম action-এ পাস করি ঘটনা।

// File: app/page.jsx
 
// Import the server action
import { publishNotification } from './actions'
 
const Home = () => {
 return (
 <>
 <div>
 <form
 
 /* set the server action to invoked as form is submitted */
 action={publishNotification}
 
 >
 {/* Place a client side form component here */}
 </form>
 </div>
 </>
 )
}
 
export default Home

React এর useFormStatus হুকের সাথে ফর্ম জমা দেওয়ার সময় মুলতুবি অবস্থা প্রদর্শন করতে Next.js ফ্রন্টএন্ড সেটআপ করুন

নিম্নলিখিত কোডটি ফর্ম জমা দেওয়ার জন্য একটি Next.js ফর্ম ক্লায়েন্ট সাইড কম্পোনেন্টের সেটআপ প্রদর্শন করে এবং একটি pending প্রদর্শন করে প্রতিক্রিয়ার useFormStatus ব্যবহার করে রাজ্য হুক আসুন কোডের মূল উপাদানগুলিকে ভেঙে ফেলি:

  • সম্প্রতি প্রকাশিত [useFormStatus আমদানি করা হচ্ছে প্রতিক্রিয়া থেকে হুক](https://react.dev/reference/react-dom/hooks/useFormStatus), যা আপনাকে সর্বশেষ ফর্ম জমা দেওয়ার স্ট্যাটাস তথ্য দেয়।
  • pending ব্যবহার করে স্টেট রিঅ্যাকটিভ ভেরিয়েবল নির্দেশ করে যে ফর্ম জমা দেওয়া চলছে কিনা।
  • যদি জমা দেওয়া মুলতুবি না থাকে, reset ফর্ম।
  • pending ব্যবহার করুন ফর্মের শর্তসাপেক্ষ অবস্থা দেখাতে বুলিয়ান।
'use client'
 
import { useEffect } from 'react'
import { useFormStatus } from 'react-dom'
 
const Form = () => {
 
 // Use React's useFormStatus hook to detect form submission state
 const { pending } = useFormStatus()
 
 useEffect(() => {
 // If the form is not pending, reset the form
 if (!pending) document.getElementById('publish-form').reset()
 }, [pending])
 
 return (
 <>
 <input placeholder="Your message" className="border rounded px-3 outline-none focus:border-black/50 py-2" type="text" name="message" required />
 <button
 /* Disable button click while the form submission is pending */
 disabled={pending}
 className="hover:border-black/50 max-w-max border rounded py-1 px-3" type="submit"
 >
 {/* Display "pending" state placeholder */}
 {pending ? (
 <div className="flex flex-row gap-x-2 items-center">
 <div className="animate-spin border border-gray-800 rounded-full h-[15px] w-[15px]"></div>
 <span>Publishing</span>
 </div>
 ) : (
 <>Publish Notification &rarr;</>
 )}
 </button>
 </>
 )
}
 
export default Form

সার্ভার-প্রেরিত ইভেন্টগুলি অবিরামভাবে শোনার জন্য Next.js ফ্রন্টএন্ড সেটআপ করুন

এই বিভাগে, আমরা শিখব কিভাবে সার্ভার-প্রেরিত ইভেন্টস এপিআই বার্তাগুলিতে একটি ন্যূনতম শ্রোতা সেটআপ করতে হয় এবং SSE API-এর সাথে সংযোগ বজায় রাখার একটি পদ্ধতি।

প্রতিক্রিয়া ফ্রন্টেন্ডে সার্ভার-প্রেরিত ইভেন্ট এপিআই শোনা

প্রতিক্রিয়াতে আমাদের ক্লায়েন্ট সাইড কম্পোনেন্টে SSE API শোনার জন্য, আমরা useEffect ব্যবহার করি হুক SSE API এর সাথে একটি সংযোগ স্থাপন করতে, একটি নতুন EventSource তৈরি করুন৷ উদাহরণ /api/stream নির্দেশ করে শেষ বিন্দু তারপর message এর জন্য একটি ইভেন্ট লিসেনার সংযুক্ত করুন ইভেন্ট, যেখানে স্ট্রীম থেকে ইনকামিং ডেটা JSON হিসাবে পার্স করা হয় এবং আরও প্রক্রিয়া করা হয় বা কম্পোনেন্টে প্রদর্শিত হয়।

অবশেষে, কম্পোনেন্ট আনমাউন্ট করা হলে SSE সংযোগ বন্ধ করার জন্য কোডটিতে একটি ক্লিনআপ ফাংশন অন্তর্ভুক্ত থাকে, সম্ভাব্য মেমরি লিক প্রতিরোধ করে।

import { useEffect, useState } from 'react'
 
const ClientSideComponent = () => {
 
 useEffect(() => {
 
 // Initiate the first call to connect to SSE API
 const eventSource = new EventSource('/api/stream')
 
 eventSource.addEventListener('message', (event) => {
 // Parse the data received from the stream into JSON
 // Add it the list of messages seen on the page
 const tmp = JSON.parse(event.data)
 // Do something with the obtained message
 })
 
 // As the component unmounts, close listener to SSE API
 return () => {
 eventSource.close()
 }
 
 }, [])
 
 return <></>
}
 
export default ClientSideComponent

প্রতিক্রিয়া ফ্রন্টেন্ডে সার্ভার-প্রেরিত ইভেন্ট এপিআই-এর সাথে অবিরাম সংযোগ

প্রতিক্রিয়া উপাদানের উন্নত সংস্করণে, আমরা ত্রুটিগুলি পরিচালনা করে এবং স্বয়ংক্রিয়ভাবে পুনরায় সংযোগের মাধ্যমে SSE API-এর সাথে একটি অবিচ্ছিন্ন এবং অবিরাম সংযোগ নিশ্চিত করার জন্য একটি প্রক্রিয়া প্রয়োগ করেছি৷

এটি connectToStream এর মাধ্যমে অর্জন করা হয় ফাংশন যা SSE API-এর সাথে সংযোগ স্থাপন ও বজায় রাখার জন্য দায়ী।

এখানে এর কার্যকারিতাগুলির একটি ব্রেকডাউন রয়েছে 👇🏻

  1. প্রাথমিক সংযোগ এবং বার্তা পরিচালনা:

ফাংশনটি একটি নতুন EventSource তৈরি করে উদাহরণ, /api/stream-এর সাথে সংযোগ করা শেষ বিন্দু।

// Function to take care of initial connect to the SSE API
// Also, it reconnects to the SSE API as soon as it shuts down
// This keeps the connection alive - forever with micro second delays
const connectToStream = () => {
 // Connect to /api/stream as the SSE API source
 const eventSource = new EventSource('/api/stream')
 // ..
}

আরও, এটি message-এর জন্য একটি ইভেন্ট লিসেনার সেট আপ করে৷ ইভেন্ট, যেখানে স্ট্রীম থেকে ইনকামিং ডেটা JSON হিসাবে পার্স করা হয়। পার্স করা ডেটা তারপরে প্রক্রিয়াকরণ বা প্রতিক্রিয়া উপাদানে প্রদর্শিত হতে পারে।

const connectToStream = () => {
 // ...
 eventSource.addEventListener('message', (event) => {
 // Parse the data received from the stream into JSON
 // Add it the list of messages seen on the page
 const tmp = JSON.parse(event.data)
 setPosts((prevPosts) => [...prevPosts, tmp])
 })
 // ...
}
  1. ত্রুটি পরিচালনা এবং স্বয়ংক্রিয় পুনঃসংযোগ:

error-এর জন্য একটি অতিরিক্ত ইভেন্ট শ্রোতা সেট করা আছে ঘটনা কোনো ত্রুটির ক্ষেত্রে, যেমন একটি সংযোগ ব্যর্থতা, ইভেন্ট উত্স বন্ধ করা হয়৷

বন্ধ করার পরে, ফাংশনটি setTimeout ব্যবহার করে 1 মিলিসেকেন্ডের ন্যূনতম বিলম্বের পরে একটি পুনঃসংযোগ ট্রিগার করতে। এই ছোট বিলম্ব দ্রুত সংযোগ প্রচেষ্টার সাথে সার্ভারকে অভিভূত না করে একটি মসৃণ এবং অবিচ্ছিন্ন পুনঃসংযোগ প্রক্রিয়া তৈরি করতে সাহায্য করে

// In case of any error, close the event source
// So that it attempts to connect again
eventSource.addEventListener('error', () => {
 eventSource.close()
 setTimeout(connectToStream, 1)
})
  1. SSE API সোর্স ক্লোজার পরিচালনা করা:

onclose SSE API উৎস বন্ধ হলে ইভেন্ট সনাক্ত করতে ব্যবহার করা হয়। বন্ধ হওয়ার পরে, ফাংশনটি একটি সংক্ষিপ্ত বিলম্বের পরে স্ট্রীমের সাথে সংযোগ করার জন্য আরেকটি প্রচেষ্টার সময়সূচী করে৷

// As soon as SSE API source is closed, attempt to reconnect
eventSource.onclose = () => {
 setTimeout(connectToStream, 1)
}

এই কৌশলগুলিকে একত্রিত করে, ফাংশনটি নিশ্চিত করে যে SSE API-এর সাথে সংযোগটি অবিচল থাকে। এমনকি ত্রুটি বা বন্ধের মুখেও, প্রতিক্রিয়া উপাদানটি ন্যূনতম বিলম্বের সাথে পুনরায় সংযোগ করার চেষ্টা চালিয়ে যাবে, কার্যকরভাবে একটি অবিচ্ছিন্ন সংযোগ বজায় রাখবে।

Vercel এ স্থাপন করুন

ভার্সেলে স্থাপনের জন্য সংগ্রহস্থল প্রস্তুত। Vercel 👇🏻

এর সাথে নির্বিঘ্নে মোতায়েন করতে নীচের পদক্ষেপগুলি অনুসরণ করুন
  • একটি GitHub Repository তৈরি করুন অ্যাপ কোড সহ
  • একটি New Project তৈরি করুন ভার্সেল ড্যাশবোর্ডে
  • তৈরি করা GitHub Repository লিঙ্ক করুন আপনার নতুন প্রকল্প হিসাবে
  • নীচে স্ক্রোল করুন এবং Environment Variables আপডেট করুন .env থেকে স্থানীয়ভাবে
  • স্থাপন করুন! 🚀

রেফারেন্স


  1. কিভাবে এইচটিএমএলে সার্কেল বুলেট সহ একটি অ-ক্রমহীন তালিকা তৈরি করবেন?

  2. HTML DOM অভ্যন্তরীণ পাঠ্য সম্পত্তি

  3. একটি প্রদত্ত বাইনারি ট্রির ইনঅর্ডার রিকার্সিভ ট্রাভার্সাল করার জন্য C++ প্রোগ্রাম

  4. অ্যান্ড্রয়েডে ওয়েবভিউতে একটি ইউআরএল লোড করার সময় কীভাবে অগ্রগতি বার প্রদর্শন করবেন?