SSE (Server-Sent Events) একটি W3C মানক যা সার্ভারকে একমুখী মোডে একটি HTTP সংযোগের মাধ্যমে ক্লায়েন্টে স্ট্রিমিং ডেটা পাঠানোর অনুমতি দেয়। WebSocket এর বিপরীতে, SSE সাধারণ HTTP এর উপর কাজ করে এবং ক্লায়েন্ট প্রান্তে কোনো বিশেষ প্রোটোকল বা লাইব্রেরীর প্রয়োজন নেই। W3C HTML Living Standard (2025) স্পেসিফিকেশন অনুযায়ী, EventSource API সকল আধুনিক ব্রাউজারতে সমর্থিত, যার মধ্যে রয়েছে Chrome, Firefox, Safari এবং Edge।
মূল বিষয়সমূহ
SSE (Server-Sent Events) একটি প্রযুক্তি যা একটি ওয়েব সার্ভারকে সংযোগ স্থাপনের পর যে কোনো সময় ক্লায়েন্টে ডেটা পাঠানোর অনুমতি দেয়। এটি WHATWG দ্বারা HTML Living Standard এর অংশ হিসেবে মানকীকৃত এবং MIME ধরন text/event-stream ব্যবহার করে। SSE একটি বার্তা শনাক্তকারী, ইভেন্ট ধরন এবং পুনর্যুক্তি বিলম্ব নির্দিষ্ট করার ক্ষমতা সহ টেক্সট ডেটা প্রেরণের সমর্থন করে।
WebSocket এর বিপরীতে, যার জন্য একটি দ্বিমুখী প্রোটোকল এবং অপগ্রেড অনুরোধের প্রয়োজন, SSE সাধারণ HTTP এর উপর কাজ করে। সার্ভার Content-Type: text/event-stream হেডার সেট করে, খণ্ডাকারে ডেটা পাঠায় এবং সংযোগ খোলা রাখে। ক্লায়েন্ট ব্রাউজারের EventSource API ব্যবহার করে ডেটা গ্রহণ করে, যা স্বচালিতভাবে স্ট্রিম পার্স করে এবং ইভেন্ট উৎপন্ন করে।
CanIUse (2025) অনুযায়ী, EventSource API বিশ্বব্যাপী 97.5% ব্রাউজারে সমর্থিত। এটি Internet Explorer এবং কিছু মোবাইল ব্রাউজারে (সংস্করণ 7.0 এর আগে Samsung Internet) সমর্থিত নয়। এই ক্ষেত্রের জন্য, পলিফিল আছে যা XHR স্ট্রিমিংয়ের মাধ্যমে EventSource অনুকরণ করে। SSE HTTP/1.1 পাইপলাইনিংয়ের সাথে কাজ করে না, কিন্তু HTTP/2 সার্ভার পুশের সাথে সম্পূর্ণ সংগত।
SSE 2009 সালে Server-Sent DOM Events নামে HTML5 স্পেসিফিকেশনের অংশ হিসেবে প্রস্তাবিত হয়েছিল। প্রথম বাস্তবায়ন Opera 9.0 এ, পরে Firefox 6.0 (2011), Chrome 9.0 (2011) এবং Safari 5.0 (2010) এ আসে। 2015 সালে, স্পেসিফিকেশনটি HTML Living Standard এর একটি পৃথক ডিভিশনে সরানো হয়েছিল। এক দশকের ইতিহাস সত্ত্বেও, SSE এর একমুখী প্রকৃতির কারণে WebSocket এর চেয়ে কম জনপ্রিয় রয়েছে।
SSE এর কাজ পদ্ধতি নিম্নরূপ: ক্লায়েন্ট সার্ভার এন্ডপয়েন্টের URL সহ EventSource এর একটি ইনস্টান্স তৈরি করে। ব্রাউজার Accept: text/event-stream হেডার সহ GET অনুরোধ পাঠায়। সার্ভার স্থিতি 200 OK এবং Content-Type: text/event-stream হেডার সহ জবাব দেয়, তারপর event-stream ফরম্যাটে ডেটা পাঠানো শুরু করে। সংযোগটি সক্রিয় থাকে যত্ন পর্যন্ত সার্ভার একটি সমাপ্তি সংকেত পাঠায় বা ক্লায়েন্ট close() কল করে।
সার্ভার প্রান্তে, ডেটা খণ্ডাকারে (chunked transfer encoding) পাঠানো হয়। প্রতিটি ডেটা খণ্ড একটি টেক্সট বার্তা যাতে ক্ষেত্র লাইন (event, data, id, retry) থাকে। সার্ভার যে কোনো সময় বার্তা পাঠাতে পারে, যা SSE কে বিজ্ঞপ্তি এবং অবস্থা আপডেটের জন্য আদর্শ করে তোলে। WebSocket এর মতো সংযোগের জন্য নিরন্তর হার্টবিট প্যাকেট আদান-প্রদানের প্রয়োজন নেই, যদিও retry ক্ষেত্রটি পুনর্যুক্তি ফ্রিকোয়েন্সি নিয়ন্ত্রণ করে।
পরিদর্শন পরীক্ষা (2024) অনুযায়ী, SSE 256 বাইটের বার্তা আকারের জন্য প্রতি সংযোগে প্রতি সেকেন্ডে 10,000 বার্তা পর্যন্ত থ্রুপুট প্রদান করে। সার্ভার প্রান্তে, প্রতিটি SSE সংযোগ প্রায় 5–10 KB মেমরি ব্যবহার করে, যা 1 GB RAM এর সাথে একটি সার্ভারকে 50,000+ যুগপৎ সংযোগ সমর্থন করতে দেয়। একটি বাইনারি প্রোটোকলের অনুপস্থিতির কারণে এটি WebSocket এর চেয়ে উল্লেখযোগ্যভাবে কম।
text/event-stream ফরম্যাট একটি সহজ টেক্সট প্রোটোকল যেখানে প্রতিটি বার্তা নতুন লাইন অক্ষরের মাধ্যমে পৃথক করা নামিত ক্ষেত্র নিয়ে গঠিত। প্রতিটি ক্ষেত্রের ফরম্যাট হল “ক্ষেত্রের নাম: মান”। বার্তাগুলি দুটি নতুন লাইন অক্ষর (\n\n) দ্বারা পৃথক করা হয়।
সমর্থিত ক্ষেত্রসমূহ: event (ইভেন্ট ধরন, ডিফল্ট message), data (ডেটা স্ট্রিং, মাল্টিলাইন হতে পারে), id (শেষ ইভেন্ট শনাক্তকারী, Last-Event-ID এ সংরক্ষিত), retry (মিলিসেকেন্ডে পুনর্যুক্তি সময়). মন্তব্য কলন (:) দিয়ে শুরু হয় এবং পার্সার দ্বারা উপেক্ষিত হয়, কিন্তু হার্টবিটের জন্য ব্যবহৃত হতে পারে।
| ক্ষেত্র | আবশ্যক | উদ্দেশ্য |
|---|---|---|
| event | না | ইভেন্ট ধরন (ডিফল্ট message) |
| data | হ্যাঁ | বার্তা ডেটা স্ট্রিং |
| id | না | Last-Event-ID এর জন্য ইভেন্ট শনাক্তকারী |
| retry | না | মিলিসেকেন্ডে পুনর্যুক্তি বিলম্ব |
: heartbeat comment
event: update
data: {"user": "Alice", "action": "typing"}
id: 1001
event: notification
data: {"type": "info", "text": "New version available"}
data: {"type": "action", "url": "/upgrade"}
retry: 3000
event: close
data: Session ended
EventSource API SSE গ্রহণের জন্য একটি নির্মিত ব্রাউজার ইন্টারফেস। একটি সংযোগ তৈরিতে, এন্ডপয়েন্ট URL সহ কনস্ট্রাক্টর কল করা যথেষ্ট। EventSource স্বচালিতভাবে সংযোগ স্থাপন করে, পুনর্যুক্তি পরিচালনা করে এবং আগত বার্তাগুলিকে JavaScript ইভেন্টে পার্স করে।
EventSource ইভেন্ট: open (সংযোগ স্থাপিত), message (ইভেন্ট নির্দিষ্ট ছাড়া বার্তা গ্রহণ), error (সংযোগ ত্রুটি). কাস্টম ইভেন্ট (event: custom) এর জন্য, আপনি ইভেন্ট নামের সাথে addEventListener ব্যবহার করতে পারেন। EventSource পুনর্যুক্তির সময় স্বচালিতভাবে Last-Event-ID হেডার পাঠায়, যা সার্ভারকে স্ট্রিমটি যেখান থেকে বাধিত হয়েছিল সেখান থেকে পুনরায় শুরু করতে দেয়।
MDN ডকুমেন্টেশন (2025) অনুযায়ী, EventSource CORS এবং ক্রেডেন্শিয়াল ট্রান্সমিশন (withCredentials) সমর্থন করে। কাস্টম হেডার বা অনুরোধ বাডি পাঠানোর জন্য EventSource উপযুক্ত নয় — fetch + ReadableStream ব্যবহার করে ম্যানুয়াল বাস্তবায়নের প্রয়োজন। EventSource বাইনারি ডেটা সমর্থন করে না — শুধুমাত্র টেক্সট এবং JSON।
const eventSource = new EventSource('/api/events/stream');
eventSource.addEventListener('open', () => {
console.log('SSE সংযোগ খুলা');
});
eventSource.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('গ্রহণ করা হয়েছে:', data);
renderUpdate(data);
});
eventSource.addEventListener('notification', (event) => {
const notification = JSON.parse(event.data);
showNotification(notification.text);
});
eventSource.addEventListener('error', (error) => {
console.error('SSE ত্রুটি:', error);
// ব্রাউজার স্বচালিতভাবে পুনর্যুক্ত হয়
});
// সংযোগ বন্ধ করুন
eventSource.close();
SSE এবং WebSocket রিয়াল-টাইম যোগাযোগের জন্য ভিন্ন প্রযুক্তি, প্রত্যেকটির নিজস্ব শক্তি রয়েছে। WebSocket দ্বিমুখী ডেটা আদান-প্রদানের জন্য (চ্যাট, গেম, সহযোগিতামূলক সম্পাদন) উপযুক্ত, যখন SSE সার্ভার থেকে ক্লায়েন্টে একমুখী প্রবাহের জন্য (বিজ্ঞপ্তি, সংবাদ ফীড, টাইকার) ব্যবহৃত হয়।
মূল পার্থক্য হল WebSocket এর HTTP/1.1 থেকে WebSocket প্রোটোকল (ws://) এ একটি অপগ্রেড অনুরোধের প্রয়োজন, যা কর্পোরেট প্রক্সি দ্বারা অবরুদ্ধ হতে পারে। SSE সাধারণ HTTP এর উপর কাজ করে, যে কোনো প্রক্সির মাধ্যমে যায় এবং সার্ভারের কোনো বিশেষ কনফিগরেশনের প্রয়োজন নেই। SSE বাস্তবায়ন করাও সহজ — সার্ভারের কোনো অতিরিক্ত লাইব্রেরীর প্রয়োজন নেই, শুধুমাত্র সঠিকভাবে HTTP প্রতিক্রিয়া গঠন করতে হবে।
তুলনামূলক পরীক্ষা (2024) অনুযায়ী, একটি সার্ভার প্রক্রিয়ায় SSE সহজ প্রোটোকলের কারণে WebSocket এর চেয়ে 30–50% বেশি সংযোগ সমর্থন করে। তবে, SSE এর লেটেন্সি বেশি (50–200 মিলিসেকেন্ড বাম 10–50 মিলিসেকেন্ড WebSocket) কারণ SSE পূর্ণ দ্বিমুখী বাইনারি ফ্রেম সহ স্ত্রিমিংয়ের পরিবর্তে চাঙ্কড HTTP ব্যবহার করে।
| বৈশিষ্ট্য | SSE | WebSocket |
|---|---|---|
| দিক | সার্ভার → ক্লায়েন্ট | দ্বিমুখী |
| প্রোটোকল | HTTP (text/event-stream) | ws:// / wss:// (RFC 6455) |
| ব্রাউজার | 97.5% (নির্মিত EventSource) | 97% (নির্মিত WebSocket) |
| ডেটা | শুধুমাত্র টেক্সট / JSON | টেক্সট + বাইনারি (Blob, ArrayBuffer) |
| প্রক্সি পরিচালনা | যে কোনো প্রক্সির মাধ্যমে যায় | প্রক্সি কনফিগরেশন প্রয়োজন |
| পুনর্যুক্তি | স্বচালিত (ব্রাউজার) | ম্যানুয়াল বাস্তবায়ন |
| ইতিহাস | Last-Event-ID | কোনো নির্মিত ইতিহাস নেই |
সার্ভারে SSE বাস্তবায়ন করতে লাইব্রেরির প্রয়োজন নেই — শুধু সঠিক HTTP হেডার সেট করুন এবং text/event-stream ফরম্যাটে ডেটা পাঠান। আসুন নির্মিত http মডিউল ব্যবহার করে Node.js এর একটি উদাহরণ দেখি। সার্ভার Content-Type এবং Cache-Control হেডার সেট করে, তারপর প্রতি N সেকেন্ডে বার্তা পাঠায়।
MDN Web Docs (2025) অনুযায়ী, SSE এর জন্য প্রয়োজনীয় হেডার হল: Content-Type: text/event-stream, Cache-Control: no-cache এবং Connection: keep-alive। Cache-Control ছাড়া, ব্রাউজার SSE স্ট্রিম কেশ করতে পারে, যা ডেলিভারি বন্ধ করে দেবে। Connection: keep-alive ব্রাউজারকে স্পষ্টভাবে সংযোগ খোলা রাখতে বলে।
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
let eventId = 0;
const interval = setInterval(() => {
eventId++;
res.write(`id: ${eventId}\n`);
res.write(`event: update\n`);
res.write(`data: {"time": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
}, 2000);
req.on('close', () => {
clearInterval(interval);
});
}).listen(3000);
from flask import Response, Flask
import time
import json
app = Flask(__name__)
@app.route('/stream')
def stream():
def generate():
event_id = 0
while True:
event_id += 1
data = json.dumps(
{'ticker': 'AAPL', 'price': 150.25})
yield f'id: {event_id}\nevent: price\ndata: {data}\n\n'
time.sleep(1)
return Response(generate(),
mimetype='text/event-stream')
মোবাইল অ্যাপে SSE ব্যবহার iOS এবং Android এর জন্য নির্মিত EventSource বাস্তবায়নের অভাবে সীমিত। মোবাইল প্লেটফর্মগুলিতে, SSE তৃতীয় পক্ষের লাইব্রেরির মাধ্যমে বাস্তবায়িত হয়: iOS এ — URLSession এর সাথে NSURLProtocol ব্যবহার করে, Android এ — OkHttp এর সাথে SSE সমর্থন (okhttp-sse) ব্যবহার করে। React Native এবং Flutter এর জন্য, EventSource অনুকরণ করে এমন প্যাকেজ উপলব্ধ।
iOS এ, নির্মিত SSE বাস্তবায়ন URLSessionDataDelegate এর মাধ্যমে সম্ভব। urlSession(_:dataTask:didReceive:) পদ্ধতিতে ডেটা গ্রহণের সময়, অ্যাপ একটি বাফার জমা করে এবং event-stream ফরম্যাট ম্যানুয়ালি পার্স করে। iOS ডেভেলপমেন্ট ব্লগ (2024) অনুযায়ী, হার্টবিট প্যাকেটের অনুপস্থিতির কারণে iOS এ SSE এর সাথে ব্যাটারি খরচ নিরন্তর WebSocket সংযোগের চেয়ে 40% কম।
Android এ, OkHttp SSE স্ট্রিমে সাবস্ক্রাইব করার জন্য EventSource.Factory ক্লাস প্রদান করে। Android অ্যাপ FCM উপলব্ধ না থাকলে বিজ্ঞপ্তির জন্য, বা পর্দার ডেটা সিংকের জন্য SSE ব্যবহার করতে পারে। Android এ SSE দীর্ঘজীবী পর্দার কাজের জন্য WorkManager এর সাথে ভালোভাবে কাজ করে। OkHttp ডকুমেন্টেশন (2025) অনুযায়ী, okhttp-sse কাস্টম লিসনার সহ স্বচালিত পুনর্যুক্তি সমর্থন করে।
প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী
SSE HTTP এর উপর একমুখι সংপ্রেষণ (সার্ভার → ক্লায়েন্ট), ক্লায়েন্টে কোনো লাইব্রেরীর প্রয়োজন নেই। WebSocket একটি বাইনারি প্রোটোকল সহ দ্বিমুখী সংপ্রেষণ। SSE বাস্তবায়ন করা সহজ, WebSocket সেই কাজের জন্য উপযুক্ত যেখানে ক্লায়েন্টও ডেটা পাঠায়।
না, SSE শুধুমাত্র টেক্সট ডেটা প্রেরণ করে। বাইনারি ডেটা (ছবি, অডিও) এর জন্য Base64 এনকোডিং প্রয়োজন, যা আকার 33% বাড়ায়। বাইনারি স্ট্রিমের জন্য WebSocket ব্যবহার করা ভালো।
EventSource বিছেদের সময় স্বচালিতভাবে পুনর্যুক্ত হয়। বিলম্ব সময় স্ট্রিমের retry ক্ষেত্র (ডিফল্ট 1000 মিলিসেকেন্ড) দ্বারা নির্ধারিত হয়। পুনর্যুক্তির সময়, ব্রাউজার Last-Event-ID হেডার পাঠায়, যা সার্ভারকে স্ট্রিমটি যেখান থেকে বাধিত হয়েছিল সেখান থেকে পুনরায় শুরু করতে দেয়।
প্রতিটি ব্রাউজারের একটি ডোমেইনে যুগপৎ HTTP সংযোগের সীমা রয়েছে। HTTP/1.1 এর জন্য — প্রতি ডোমেইন 6–8 সংযোগ, HTTP/2 এর জন্য — 100 পর্যন্ত। SSE একটি সংযোগ ব্যবহার করে, তাই অন্য অনুরোধের সাথে কোনো প্রতিযোগিতা নেই।
SSE শুধুমাত্র বার্তা গ্রহণের (আগত) জন্য উপযুক্ত। বার্তা পাঠানোর (বহিরগত) জন্য একটি পৃথক্ HTTP অনুরোধ (POST) প্রয়োজন। সম্পূর্ণ কার্যক্ষম চ্যাটের জন্য, একটি সংযোগে দ্বিমুখী যোগাযোগের জন্য WebSocket বা Socket.IO ব্যবহার করা অধিক সুবিধাজনক।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন