প্রকাশিত: ৮ জুন, ২০২০
WebTransport হলো একটি ওয়েব এপিআই যা দ্বিমুখী পরিবহন হিসেবে HTTP/3 প্রোটোকল ব্যবহার করে। এটি একটি ওয়েব ক্লায়েন্ট এবং একটি HTTP/3 সার্ভারের মধ্যে দ্বিমুখী যোগাযোগের জন্য তৈরি। এটি এর ডেটাগ্রাম এপিআই ব্যবহার করে অনির্ভরযোগ্যভাবে এবং এর স্ট্রিমস এপিআই ব্যবহার করে নির্ভরযোগ্যভাবে উভয়ভাবেই ডেটা প্রেরণ সমর্থন করে।
ডেটাগ্রাম এমন ডেটা পাঠানো এবং গ্রহণ করার জন্য আদর্শ, যার জন্য শক্তিশালী ডেলিভারি নিশ্চয়তার প্রয়োজন হয় না। ডেটার প্রতিটি প্যাকেটের আকার অন্তর্নিহিত সংযোগের সর্বোচ্চ ট্রান্সমিশন ইউনিট (MTU) দ্বারা সীমাবদ্ধ থাকে এবং সেগুলো সফলভাবে প্রেরিত হতেও পারে বা নাও হতে পারে, আর যদি স্থানান্তরিত হয়, তবে সেগুলো যেকোনো ক্রমে এসে পৌঁছাতে পারে। এই বৈশিষ্ট্যগুলো ডেটাগ্রাম এপিআই-কে স্বল্প-বিলম্বের, সর্বোত্তম-প্রচেষ্টার ডেটা ট্রান্সমিশনের জন্য আদর্শ করে তোলে। আপনি ডেটাগ্রামকে ইউজার ডেটাগ্রাম প্রোটোকল (UDP) মেসেজ হিসেবে ভাবতে পারেন, তবে এটি এনক্রিপ্টেড এবং কনজেশন-নিয়ন্ত্রিত।
অন্যদিকে, স্ট্রিমস এপিআইগুলো নির্ভরযোগ্য ও সুবিন্যস্ত ডেটা স্থানান্তর প্রদান করে। এগুলো এমন সব পরিস্থিতির জন্য বিশেষভাবে উপযোগী যেখানে আপনাকে এক বা একাধিক সুবিন্যস্ত ডেটার স্ট্রিম পাঠাতে বা গ্রহণ করতে হয়। একাধিক ওয়েবট্রান্সপোর্ট স্ট্রিম ব্যবহার করা একাধিক টিসিপি সংযোগ স্থাপনের অনুরূপ, কিন্তু যেহেতু HTTP/3 অভ্যন্তরীণভাবে অপেক্ষাকৃত হালকা QUIC প্রোটোকল ব্যবহার করে, তাই এগুলো খুব বেশি অতিরিক্ত চাপ ছাড়াই খোলা এবং বন্ধ করা যায়।
ব্যবহারের ক্ষেত্র
ডেভেলপাররা ওয়েবট্রান্সপোর্ট ব্যবহার করতে পারেন এমন কিছু সম্ভাব্য পদ্ধতির একটি সংক্ষিপ্ত তালিকা এখানে দেওয়া হলো।
- ন্যূনতম ল্যাটেন্সিতে ছোট, অনির্ভরযোগ্য এবং এলোমেলো বার্তার মাধ্যমে নিয়মিত বিরতিতে একটি সার্ভারে গেমের অবস্থা পাঠানো।
- অন্যান্য ডেটা স্ট্রিম থেকে স্বাধীনভাবে, ন্যূনতম ল্যাটেন্সিতে সার্ভার থেকে পাঠানো মিডিয়া স্ট্রিম গ্রহণ করা।
- ওয়েব পেজ খোলা থাকা অবস্থায় সার্ভার থেকে পাঠানো নোটিফিকেশন গ্রহণ করা।
আপনি ওয়েবট্রান্সপোর্ট কীভাবে ব্যবহার করার পরিকল্পনা করছেন, সে সম্পর্কে আমরা আরও জানতে আগ্রহী।
ব্রাউজার সমর্থন
যেসব ফিচারের সার্বজনীন ব্রাউজার সমর্থন নেই, সেগুলোর ক্ষেত্রে আমরা ফিচার ডিটেকশন যোগ করার সুপারিশ করি।
অন্যান্য প্রযুক্তির সাথে সম্পর্ক
WebTransport কি WebSockets-এর বিকল্প?
হতে পারে। এমন কিছু ব্যবহারের ক্ষেত্র আছে যেখানে WebSockets বা WebTransport উভয়ই যোগাযোগের জন্য বৈধ প্রোটোকল হতে পারে।
ওয়েবসকেটস যোগাযোগ একটি একক, নির্ভরযোগ্য এবং ক্রমবিন্যস্ত বার্তা প্রবাহের উপর ভিত্তি করে তৈরি, যা কিছু নির্দিষ্ট ধরনের যোগাযোগের প্রয়োজনের জন্য যথেষ্ট। আপনার যদি এই বৈশিষ্ট্যগুলোর প্রয়োজন হয়, তবে ওয়েবট্রান্সপোর্টের স্ট্রিমস এপিআইগুলোও তা সরবরাহ করতে পারে। এর তুলনায়, ওয়েবট্রান্সপোর্টের ডেটাগ্রাম এপিআইগুলো নির্ভরযোগ্যতা বা ক্রমবিন্যাস সম্পর্কে কোনো নিশ্চয়তা ছাড়াই স্বল্প-বিলম্বের ডেলিভারি প্রদান করে, তাই এগুলো ওয়েবসকেটস-এর সরাসরি বিকল্প নয়।
যখন আপনি ডেটাগ্রাম এপিআই বা একাধিক সমান্তরাল স্ট্রিমস এপিআই ইনস্ট্যান্সের সাথে ওয়েবট্রান্সপোর্ট ব্যবহার করেন, তখন আপনাকে হেড-অফ-লাইন ব্লকিং নিয়ে চিন্তা করতে হবে না, যা ওয়েবসকেটস-এর ক্ষেত্রে একটি সমস্যা হতে পারে। এছাড়াও, নতুন সংযোগ স্থাপনের ক্ষেত্রে পারফরম্যান্সের সুবিধা রয়েছে, কারণ এর অন্তর্নিহিত QUIC হ্যান্ডশেক , TCP ওভার TLS চালু করার চেয়ে দ্রুততর।
WebTransport একটি নতুন খসড়া স্পেসিফিকেশনের অংশ, এবং সেই কারণে ক্লায়েন্ট ও সার্ভার লাইব্রেরিগুলোকে ঘিরে WebSocket ইকোসিস্টেমটি এখন অনেক বেশি শক্তিশালী। আপনার যদি এমন কিছুর প্রয়োজন হয় যা সাধারণ সার্ভার সেটআপের সাথে কোনো অতিরিক্ত কনফিগারেশন ছাড়াই কাজ করে এবং যার ব্যাপক ওয়েব ক্লায়েন্ট সাপোর্ট রয়েছে, তবে বর্তমানে WebSockets একটি উত্তম বিকল্প।
WebTransport কি UDP সকেট API-এর সমান?
না, WebTransport কোনো UDP সকেট এপিআই নয়। যদিও WebTransport, HTTP/3 ব্যবহার করে, যা আবার নেপথ্যে UDP ব্যবহার করে, তবুও এনক্রিপশন এবং কনজেশন কন্ট্রোল সংক্রান্ত কিছু আবশ্যিক শর্ত রয়েছে, যা এটিকে একটি সাধারণ UDP সকেট এপিআই-এর চেয়ে বেশি কিছু করে তোলে।
WebTransport কি WebRTC ডেটা চ্যানেলের একটি বিকল্প?
হ্যাঁ, ক্লায়েন্ট-সার্ভার সংযোগের জন্য। WebTransport-এর অনেক বৈশিষ্ট্যই WebRTC ডেটা চ্যানেলের মতো, যদিও এর অন্তর্নিহিত প্রোটোকলগুলো ভিন্ন।
সাধারণত, একটি HTTP/3-উপযোগী সার্ভার চালানোর জন্য একটি WebRTC সার্ভার রক্ষণাবেক্ষণের চেয়ে কম সেটআপ এবং কনফিগারেশনের প্রয়োজন হয়, কারণ একটি কার্যকর ট্রান্সপোর্ট পাওয়ার জন্য একাধিক প্রোটোকল ( ICE , DTLS , এবং SCTP ) বোঝা আবশ্যক। WebRTC-তে আরও অনেক জটিল বিষয় জড়িত থাকে, যার ফলে ক্লায়েন্ট/সার্ভার নেগোসিয়েশন ব্যর্থ হতে পারে।
WebTransport API-টি ওয়েব ডেভেলপারদের ব্যবহারের কথা মাথায় রেখে ডিজাইন করা হয়েছে, এবং এটি WebRTC-এর ডেটা চ্যানেল ইন্টারফেস ব্যবহারের চেয়ে আধুনিক ওয়েব প্ল্যাটফর্ম কোড লেখার মতোই মনে হবে। WebRTC-এর থেকে ভিন্ন , WebTransport ওয়েব ওয়ার্কার্স- এর ভেতরে সমর্থিত, যা আপনাকে একটি নির্দিষ্ট HTML পেজ থেকে স্বাধীনভাবে ক্লায়েন্ট-সার্ভার যোগাযোগ সম্পাদন করার সুযোগ দেয়। যেহেতু WebTransport একটি স্ট্রিমস -সম্মত ইন্টারফেস প্রদান করে, তাই এটি ব্যাকপ্রেশার সংক্রান্ত অপটিমাইজেশন সমর্থন করে।
তবে, আপনার যদি ইতিমধ্যেই একটি সন্তোষজনক ও কার্যকর WebRTC ক্লায়েন্ট/সার্ভার সেটআপ থাকে, তাহলে WebTransport-এ পরিবর্তন করলে খুব বেশি সুবিধা নাও পাওয়া যেতে পারে।
পরীক্ষা
WebTransport নিয়ে পরীক্ষা করার সেরা উপায় হলো একটি সামঞ্জস্যপূর্ণ HTTP/3 সার্ভার চালু করা। ক্লায়েন্ট ও সার্ভারের মধ্যে যোগাযোগ পরীক্ষা করার জন্য একটি সাধারণ জাভাস্ক্রিপ্ট ক্লায়েন্টের সাথে এই পৃষ্ঠাটি ব্যবহার করুন।
এছাড়াও, webtransport.day- তে একটি কমিউনিটি-পরিচালিত ইকো সার্ভার উপলব্ধ রয়েছে।
এপিআই ব্যবহার করুন
WebTransport আধুনিক ওয়েব প্ল্যাটফর্ম প্রিমিটিভ, যেমন Streams API-এর উপর ভিত্তি করে ডিজাইন করা হয়েছে। এটি প্রমিজের উপর ব্যাপকভাবে নির্ভর করে এবং async ও await সাথে ভালোভাবে কাজ করে।
ক্রোমিয়ামে ওয়েবট্রান্সপোর্টের বর্তমান বাস্তবায়ন তিন ধরনের স্বতন্ত্র ট্র্যাফিক সমর্থন করে: ডেটাগ্রাম, এবং একমুখী ও দ্বিমুখী উভয় প্রকার স্ট্রিম।
একটি সার্ভারের সাথে সংযোগ করুন
একটি WebTransport ইনস্ট্যান্স তৈরি করে আপনি একটি HTTP/3 সার্ভারের সাথে সংযোগ করতে পারেন। URL-এর স্কিমটি অবশ্যই https হতে হবে। আপনাকে পোর্ট নম্বরটি স্পষ্টভাবে উল্লেখ করতে হবে।
সংযোগ স্থাপিত হওয়ার জন্য অপেক্ষা করতে আপনার ready promise) ব্যবহার করা উচিত। সেটআপ সম্পূর্ণ না হওয়া পর্যন্ত এই প্রমিসটি অপূর্ণ থাকে এবং QUIC/TLS পর্যায়ে সংযোগ ব্যর্থ হলে এটি প্রত্যাখ্যাত হয়।
সংযোগটি স্বাভাবিকভাবে বন্ধ হলে closed প্রমিসটি ফুলফিল হয়, এবং সংযোগটি অপ্রত্যাশিতভাবে বন্ধ হলে রিজেক্ট হয়।
যদি ক্লায়েন্টের কোনো ত্রুটির কারণে (যেমন URL-এর পাথটি অবৈধ) সার্ভার সংযোগটি প্রত্যাখ্যান করে, তাহলে closed সংযোগটি প্রত্যাখ্যাত হয় এবং ready সংযোগটি অমীমাংসিত থেকে যায়।
const url = 'https://example.com:4999/foo/bar';
const transport = new WebTransport(url);
// Optionally, set up functions to respond to
// the connection closing:
transport.closed.then(() => {
console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
}).catch((error) => {
console.error(`The HTTP/3 connection to ${url} closed due to ${error}.`);
});
// Once .ready fulfills, the connection can be used.
await transport.ready;
ডেটাগ্রাম এপিআই
একবার আপনার সার্ভারের সাথে সংযুক্ত একটি WebTransport ইনস্ট্যান্স থাকলে, আপনি সেটি ব্যবহার করে ডেটাগ্রাম নামে পরিচিত বিচ্ছিন্ন ডেটা পাঠাতে ও গ্রহণ করতে পারবেন।
writeable গেটারটি একটি WritableStream রিটার্ন করে, যা একটি ওয়েব ক্লায়েন্ট সার্ভারে ডেটা পাঠাতে ব্যবহার করতে পারে। readable গেটারটি একটি ReadableStream রিটার্ন করে, যা আপনাকে সার্ভার থেকে ডেটা শোনার সুযোগ দেয়। উভয় স্ট্রিমই স্বভাবগতভাবে অনির্ভরযোগ্য, তাই এমন হতে পারে যে আপনার লেখা ডেটা সার্ভার গ্রহণ করবে না এবং এর বিপরীতটিও হতে পারে।
উভয় প্রকারের স্ট্রিমই ডেটা স্থানান্তরের জন্য Uint8Array ইনস্ট্যান্স ব্যবহার করে।
// Send two datagrams to the server.
const writer = transport.datagrams.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
// Read datagrams from the server.
const reader = transport.datagrams.readable.getReader();
while (true) {
const {value, done} = await reader.read();
if (done) {
break;
}
// value is a Uint8Array.
console.log(value);
}
স্ট্রিম এপিআই
একবার সার্ভারের সাথে সংযুক্ত হয়ে গেলে, আপনি WebTransport-এর Streams API ব্যবহার করে ডেটা আদান-প্রদান করতেও পারবেন।
সমস্ত স্ট্রিমের প্রতিটি খণ্ড একটি Uint8Array । ডেটাগ্রাম এপিআই-এর মতো নয়, এই স্ট্রিমগুলো নির্ভরযোগ্য। কিন্তু প্রতিটি স্ট্রিম স্বাধীন, তাই স্ট্রিমগুলোর মধ্যে ডেটার ক্রম নিশ্চিত করা যায় না।
ওয়েবট্রান্সপোর্টসেন্ডস্ট্রিম
একটি WebTransportSendStream তৈরি করা হয় ওয়েব ক্লায়েন্ট দ্বারা, একটি WebTransport ইনস্ট্যান্সের createUnidirectionalStream() মেথড ব্যবহার করে, যা WebTransportSendStream টির জন্য একটি প্রমিজ রিটার্ন করে।
সংশ্লিষ্ট HTTP/3 স্ট্রিমটি বন্ধ করতে WritableStreamDefaultWriter এর close() মেথডটি ব্যবহার করুন। ব্রাউজার সংশ্লিষ্ট স্ট্রিমটি প্রকৃতপক্ষে বন্ধ করার আগে সমস্ত অপেক্ষমান ডেটা পাঠানোর চেষ্টা করে।
// Send two Uint8Arrays to the server.
const stream = await transport.createUnidirectionalStream();
const writer = stream.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
try {
await writer.close();
console.log('All data has been sent.');
} catch (error) {
console.error(`An error occurred: ${error}`);
}
একইভাবে, সার্ভারে একটি RESET_STREAM পাঠাতে WritableStreamDefaultWriter এর abort() মেথডটি ব্যবহার করুন। abort() ব্যবহার করার সময়, ব্রাউজারটি এখনও পাঠানো হয়নি এমন যেকোনো অপেক্ষমান ডেটা বাতিল করে দিতে পারে।
const ws = await transport.createUnidirectionalStream();
const writer = ws.getWriter();
writer.write(...);
writer.write(...);
await writer.abort();
// Not all the data may have been written.
ওয়েবট্রান্সপোর্টরিসিভস্ট্রিম
সার্ভার WebTransportReceiveStream শুরু করে। একটি ওয়েব ক্লায়েন্টের জন্য WebTransportReceiveStream পাওয়া একটি দুই-ধাপের প্রক্রিয়া। প্রথমত, ক্লায়েন্ট একটি WebTransport ইনস্ট্যান্সের incomingUnidirectionalStreams অ্যাট্রিবিউটকে কল করে, যা একটি ReadableStream রিটার্ন করে। সেই ReadableStream এর প্রতিটি অংশই আবার একটি WebTransportReceiveStream , যা সার্ভার দ্বারা প্রেরিত Uint8Array ইনস্ট্যান্সগুলো পড়ার জন্য ব্যবহার করা যেতে পারে।
async function readFrom(receiveStream) {
const reader = receiveStream.readable.getReader();
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
// value is a Uint8Array
console.log(value);
}
}
const rs = transport.incomingUnidirectionalStreams;
const reader = rs.getReader();
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
// value is an instance of WebTransportReceiveStream
await readFrom(value);
}
আপনি ReadableStreamDefaultReader এর closed প্রমিস ব্যবহার করে স্ট্রিম বন্ধ হওয়া শনাক্ত করতে পারেন। যখন অন্তর্নিহিত HTTP/3 স্ট্রিমটি FIN বিট দিয়ে বন্ধ করা হয়, তখন সমস্ত ডেটা পড়া হয়ে গেলে closed প্রমিসটি ফুলফিল হয়। যখন HTTP/3 স্ট্রিমটি হঠাৎ বন্ধ হয়ে যায় (উদাহরণস্বরূপ, RESET_STREAM দ্বারা), তখন closed প্রমিসটি রিজেক্ট হয়।
// Assume an active receiveStream
const reader = receiveStream.readable.getReader();
reader.closed.then(() => {
console.log('The receiveStream closed gracefully.');
}).catch(() => {
console.error('The receiveStream closed abruptly.');
});
ওয়েবট্রান্সপোর্টবাইডিরেকশনালস্ট্রিম
একটি WebTransportBidirectionalStream সার্ভার বা ক্লায়েন্ট উভয়ের দ্বারাই তৈরি করা যেতে পারে।
ওয়েব ক্লায়েন্টরা একটি WebTransport ইনস্ট্যান্সের createBidirectionalStream() মেথড ব্যবহার করে এটি তৈরি করতে পারে, যা একটি WebTransportBidirectionalStream জন্য একটি প্রমিজ রিটার্ন করে।
const stream = await transport.createBidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a ReadableStream
// stream.writable is a WritableStream
আপনি একটি WebTransport ইনস্ট্যান্সের incomingBidirectionalStreams অ্যাট্রিবিউটের মাধ্যমে সার্ভার দ্বারা তৈরি একটি WebTransportBidirectionalStream জন্য লিসেন করতে পারেন, যা একটি ReadableStream রিটার্ন করে। সেই ReadableStream এর প্রতিটি চাঙ্ক আবার একটি WebTransportBidirectionalStream হয়ে থাকে।
const rs = transport.incomingBidirectionalStreams;
const reader = rs.getReader();
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
// value is a WebTransportBidirectionalStream
// value.readable is a ReadableStream
// value.writable is a WritableStream
}
একটি WebTransportBidirectionalStream হলো WebTransportSendStream এবং WebTransportReceiveStream এর একটি সংমিশ্রণ মাত্র। পূর্ববর্তী দুটি বিভাগের উদাহরণগুলিতে এদের প্রত্যেকটির ব্যবহার পদ্ধতি ব্যাখ্যা করা হয়েছে।
পলিফিল
webtransport-ponyfill-websocket নামে একটি পলিফিল (অথবা বলা ভালো, এটি একটি পনিফিল যা একটি স্বতন্ত্র মডিউল হিসেবে কার্যকারিতা প্রদান করে) পাওয়া যাচ্ছে, যা WebTransport-এর কিছু বৈশিষ্ট্য বাস্তবায়ন করে। এই সমাধানটি আপনার ব্যবহারের ক্ষেত্রে কার্যকর হবে কিনা তা নির্ধারণ করতে প্রজেক্টটির README তে থাকা সীমাবদ্ধতাগুলো মনোযোগ সহকারে পড়ুন।
গোপনীয়তা এবং নিরাপত্তা সংক্রান্ত বিবেচনা
প্রামাণিক নির্দেশনার জন্য খসড়া স্পেসিফিকেশনের সংশ্লিষ্ট অংশটি দেখুন।
প্রতিক্রিয়া
এপিআই-টিতে কি এমন কিছু আছে যা ব্যবহারে অসুবিধাজনক বা প্রত্যাশা অনুযায়ী কাজ করে না? অথবা আপনার ধারণাটি বাস্তবায়নের জন্য প্রয়োজনীয় কোনো অংশ কি অনুপস্থিত?
- ওয়েব ট্রান্সপোর্ট গিটহাব রিপোতে একটি ইস্যু ফাইল করুন, অথবা বিদ্যমান কোনো ইস্যুতে আপনার মতামত যোগ করুন।
- ক্রোমিয়ামের বাস্তবায়ন সম্পর্কে একটি বাগ রিপোর্ট করুন। যতটা সম্ভব বিস্তারিত তথ্য দিন এবং বাগটি পুনরায় তৈরি করার নির্দেশনাও অন্তর্ভুক্ত করুন।
আপনার প্রকাশ্য সমর্থন ক্রোমকে ফিচারগুলোকে অগ্রাধিকার দিতে সাহায্য করে এবং অন্যান্য ব্রাউজার নির্মাতাদের দেখায় যে সেগুলোকে সমর্থন করা কতটা জরুরি।
-
#WebTransportহ্যাশট্যাগটি ব্যবহার করে @ChromiumDev-কে টুইট করুন এবং আপনি এটি কোথায় ও কীভাবে ব্যবহার করছেন তার বিবরণ দিন।
সাধারণ আলোচনা
যেসব সাধারণ প্রশ্ন বা সমস্যা অন্য কোনো বিভাগের অন্তর্ভুক্ত নয়, সেগুলোর জন্য আপনি web-transport-dev গুগল গ্রুপটি ব্যবহার করতে পারেন।
কৃতজ্ঞতা স্বীকার
আমরা ওয়েবট্রান্সপোর্ট এক্সপ্লেনার এবং খসড়া স্পেসিফিকেশন থেকে তথ্য অন্তর্ভুক্ত করেছি। এই ভিত্তি প্রদানের জন্য সংশ্লিষ্ট লেখকদের ধন্যবাদ।