WebTransport হল একটি API অফার করে লো-লেটেন্সি, দ্বিমুখী, ক্লায়েন্ট-সার্ভার মেসেজিং। এর ব্যবহারের ক্ষেত্রে এবং কীভাবে বাস্তবায়নের ভবিষ্যত সম্পর্কে প্রতিক্রিয়া জানাতে হয় সে সম্পর্কে আরও জানুন।
পটভূমি
WebTransport কি?
WebTransport হল একটি ওয়েব API যা দ্বিমুখী পরিবহন হিসাবে HTTP/3 প্রোটোকল ব্যবহার করে। এটি একটি ওয়েব ক্লায়েন্ট এবং একটি HTTP/3 সার্ভারের মধ্যে দ্বিমুখী যোগাযোগের উদ্দেশ্যে। এটি তার ডেটাগ্রাম API-এর মাধ্যমে অবিশ্বস্তভাবে এবং এর স্ট্রিম API-এর মাধ্যমে নির্ভরযোগ্যভাবে ডেটা পাঠানো সমর্থন করে।
ডেটাগ্রামগুলি এমন ডেটা পাঠানো এবং গ্রহণ করার জন্য আদর্শ যেগুলির শক্তিশালী ডেলিভারি গ্যারান্টির প্রয়োজন নেই৷ ডেটার পৃথক প্যাকেটগুলি অন্তর্নিহিত সংযোগের সর্বাধিক ট্রান্সমিশন ইউনিট (MTU) দ্বারা আকারে সীমিত, এবং সফলভাবে প্রেরণ করা হতে পারে বা নাও হতে পারে, এবং যদি সেগুলি স্থানান্তর করা হয় তবে সেগুলি একটি নির্বিচারে আসতে পারে৷ এই বৈশিষ্ট্যগুলি ডেটাগ্রাম API-গুলিকে কম-বিলম্বিত, সর্বোত্তম-প্রচেষ্টা ডেটা ট্রান্সমিশনের জন্য আদর্শ করে তোলে। আপনি ডেটাগ্রামগুলিকে ব্যবহারকারী ডেটাগ্রাম প্রোটোকল (UDP) বার্তা হিসাবে ভাবতে পারেন, তবে এনক্রিপ্ট করা এবং যানজট-নিয়ন্ত্রিত।
বিপরীতে, স্ট্রীম API গুলি নির্ভরযোগ্য , অর্ডারকৃত ডেটা স্থানান্তর প্রদান করে৷ এগুলি এমন পরিস্থিতিতে উপযুক্ত যেখানে আপনাকে অর্ডার করা ডেটার এক বা একাধিক স্ট্রিম পাঠাতে বা গ্রহণ করতে হবে। একাধিক ওয়েবট্রান্সপোর্ট স্ট্রীম ব্যবহার করা একাধিক টিসিপি সংযোগ স্থাপনের অনুরূপ, কিন্তু যেহেতু HTTP/3 হুডের নীচে হালকা-ওজন QUIC প্রোটোকল ব্যবহার করে, সেগুলি যতটা ওভারহেড ছাড়াই খোলা এবং বন্ধ করা যেতে পারে।
কেস ব্যবহার করুন
এটি সম্ভাব্য উপায়গুলির একটি ছোট তালিকা যা বিকাশকারীরা WebTransport ব্যবহার করতে পারে৷
- ছোট, অবিশ্বস্ত, অর্ডারের বাইরের বার্তাগুলির মাধ্যমে একটি সার্ভারে ন্যূনতম লেটেন্সি সহ একটি নিয়মিত বিরতিতে গেমের অবস্থা পাঠানো।
- অন্যান্য ডেটা স্ট্রীম থেকে স্বাধীন, ন্যূনতম লেটেন্সি সহ একটি সার্ভার থেকে পুশ করা মিডিয়া স্ট্রিমগুলি গ্রহণ করা৷
- একটি ওয়েব পৃষ্ঠা খোলা থাকা অবস্থায় সার্ভার থেকে বিজ্ঞপ্তি প্রাপ্তি।
আপনি কিভাবে WebTransport ব্যবহার করার পরিকল্পনা করছেন সে সম্পর্কে আমরা আরও শুনতে আগ্রহী।
ব্রাউজার সমর্থন
সার্বজনীন ব্রাউজার সমর্থন নেই এমন সমস্ত বৈশিষ্ট্যগুলির মতো, বৈশিষ্ট্য সনাক্তকরণের মাধ্যমে রক্ষণাত্মকভাবে কোডিং করা একটি সর্বোত্তম অনুশীলন।
বর্তমান অবস্থা
ধাপ | স্ট্যাটাস |
---|---|
1. ব্যাখ্যাকারী তৈরি করুন | সম্পূর্ণ |
2. স্পেসিফিকেশনের প্রাথমিক খসড়া তৈরি করুন | সম্পূর্ণ |
3. প্রতিক্রিয়া সংগ্রহ করুন এবং নকশা পুনরাবৃত্তি করুন | সম্পূর্ণ |
4. মূল বিচার | সম্পূর্ণ |
5. লঞ্চ করুন | ক্রোমিয়াম 97 |
অন্যান্য প্রযুক্তির সাথে WebTransport-এর সম্পর্ক
WebTransport কি WebSockets এর প্রতিস্থাপন?
হতে পারে। এমন কিছু ব্যবহার আছে যেখানে WebSockets বা WebTransport ব্যবহার করার জন্য বৈধ যোগাযোগ প্রোটোকল হতে পারে।
WebSockets যোগাযোগগুলি একটি একক, নির্ভরযোগ্য, অর্ডারকৃত বার্তাগুলির প্রবাহের চারপাশে তৈরি করা হয়, যা কিছু ধরণের যোগাযোগের প্রয়োজনের জন্য ভাল। আপনার যদি সেই বৈশিষ্ট্যগুলির প্রয়োজন হয়, তাহলে WebTransport-এর স্ট্রীম APIগুলিও সেগুলি প্রদান করতে পারে৷ তুলনামূলকভাবে, WebTransport-এর ডেটাগ্রাম API গুলি নির্ভরযোগ্যতা বা অর্ডার দেওয়ার গ্যারান্টি ছাড়াই কম-বিলম্বিত ডেলিভারি প্রদান করে, তাই তারা WebSockets-এর জন্য সরাসরি প্রতিস্থাপন নয়।
WebTransport ব্যবহার করে, ডেটাগ্রাম এপিআই-এর মাধ্যমে বা একাধিক সমবর্তী স্ট্রীম API ইন্সট্যান্সের মাধ্যমে, মানে হল যে আপনাকে হেড-অফ-লাইন ব্লক করা নিয়ে চিন্তা করতে হবে না, যা WebSockets-এর সাথে সমস্যা হতে পারে। অতিরিক্তভাবে, নতুন সংযোগ স্থাপন করার সময় কর্মক্ষমতার সুবিধা রয়েছে, কারণ অন্তর্নিহিত QUIC হ্যান্ডশেক TLS এর মাধ্যমে TCP শুরু করার চেয়ে দ্রুততর।
ওয়েব ট্রান্সপোর্ট একটি নতুন খসড়া স্পেসিফিকেশনের অংশ, এবং ক্লায়েন্ট এবং সার্ভার লাইব্রেরির চারপাশে ওয়েবসকেট ইকোসিস্টেম বর্তমানে অনেক বেশি শক্তিশালী। আপনার যদি এমন কিছুর প্রয়োজন হয় যা সাধারণ সার্ভার সেটআপের সাথে "বাক্সের বাইরে" কাজ করে, এবং বিস্তৃত ওয়েব ক্লায়েন্ট সমর্থন সহ, WebSockets আজ একটি ভাল পছন্দ।
WebTransport একটি UDP সকেট API হিসাবে একই?
না। WebTransport একটি UDP সকেট API নয়। যদিও WebTransport HTTP/3 ব্যবহার করে, যেটি UDP "হুডের নীচে" ব্যবহার করে, WebTransport-এর এনক্রিপশন এবং কনজেশন নিয়ন্ত্রণের প্রয়োজনীয়তা রয়েছে যা এটিকে একটি মৌলিক UDP সকেট API থেকে বেশি করে তোলে।
WebTransport কি WebRTC ডেটা চ্যানেলের বিকল্প?
হ্যাঁ, ক্লায়েন্ট-সার্ভার সংযোগের জন্য। ওয়েব ট্রান্সপোর্ট WebRTC ডেটা চ্যানেলের মতো একই বৈশিষ্ট্যের অনেকগুলি ভাগ করে, যদিও অন্তর্নিহিত প্রোটোকলগুলি আলাদা।
সাধারণত, একটি HTTP/3-সামঞ্জস্যপূর্ণ সার্ভার চালানোর জন্য একটি WebRTC সার্ভার বজায় রাখার চেয়ে কম সেটআপ এবং কনফিগারেশনের প্রয়োজন হয়, যার মধ্যে একটি কার্যকরী পরিবহন পেতে একাধিক প্রোটোকল ( ICE , DTLS , এবং SCTP ) বোঝা জড়িত৷ WebRTC-তে আরও অনেক চলমান অংশ রয়েছে যা ব্যর্থ ক্লায়েন্ট/সার্ভার আলোচনার দিকে নিয়ে যেতে পারে।
WebTransport APIটি ওয়েব ডেভেলপার ব্যবহারের ক্ষেত্রে মাথায় রেখে ডিজাইন করা হয়েছে এবং WebRTC-এর ডেটা চ্যানেল ইন্টারফেস ব্যবহার করার চেয়ে আধুনিক ওয়েব প্ল্যাটফর্ম কোড লেখার মতো আরও বেশি অনুভব করা উচিত। WebRTC-এর বিপরীতে , WebTransport ওয়েব ওয়ার্কার্সের অভ্যন্তরে সমর্থিত, যা আপনাকে একটি প্রদত্ত HTML পৃষ্ঠা থেকে স্বাধীনভাবে ক্লায়েন্ট-সার্ভার যোগাযোগ করতে দেয়। যেহেতু WebTransport একটি স্ট্রীম -সঙ্গতিপূর্ণ ইন্টারফেস প্রকাশ করে, এটি ব্যাকপ্রেশারের চারপাশে অপ্টিমাইজেশন সমর্থন করে।
যাইহোক, আপনার যদি ইতিমধ্যেই একটি কার্যকরী WebRTC ক্লায়েন্ট/সার্ভার সেটআপ থাকে যা আপনি সন্তুষ্ট হন, তাহলে WebTransport-এ স্যুইচ করলে অনেক সুবিধা নাও হতে পারে।
চেষ্টা করে দেখুন
WebTransport এর সাথে পরীক্ষা করার সর্বোত্তম উপায় হল একটি সামঞ্জস্যপূর্ণ HTTP/3 সার্ভার শুরু করা। তারপর আপনি ক্লায়েন্ট/সার্ভার যোগাযোগ চেষ্টা করার জন্য একটি মৌলিক জাভাস্ক্রিপ্ট ক্লায়েন্টের সাথে এই পৃষ্ঠাটি ব্যবহার করতে পারেন।
উপরন্তু, একটি সম্প্রদায়-রক্ষণাবেক্ষণ করা ইকো সার্ভার webtransport.day- এ উপলব্ধ।
API ব্যবহার করে
WebTransport আধুনিক ওয়েব প্ল্যাটফর্মের আদিম বিষয়গুলির উপরে ডিজাইন করা হয়েছে, যেমন স্ট্রীমস API । এটি প্রতিশ্রুতির উপর অনেক বেশি নির্ভর করে এবং async
এবং await
সাথে ভালভাবে কাজ করে।
Chromium-এ বর্তমান WebTransport বাস্তবায়ন তিনটি স্বতন্ত্র ধরনের ট্রাফিক সমর্থন করে: ডেটাগ্রাম, পাশাপাশি একমুখী এবং দ্বিমুখী স্ট্রীম।
একটি সার্ভারের সাথে সংযোগ করা হচ্ছে
আপনি একটি WebTransport
উদাহরণ তৈরি করে একটি HTTP/3 সার্ভারের সাথে সংযোগ করতে পারেন৷ URL এর স্কিমটি https
হওয়া উচিত। আপনাকে স্পষ্টভাবে পোর্ট নম্বর উল্লেখ করতে হবে।
সংযোগ স্থাপনের জন্য অপেক্ষা করার জন্য আপনার ready
প্রতিশ্রুতি ব্যবহার করা উচিত। সেটআপ সম্পূর্ণ না হওয়া পর্যন্ত এই প্রতিশ্রুতি পূরণ করা হবে না, এবং 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;
ডেটাগ্রাম API
একবার আপনার কাছে একটি ওয়েব ট্রান্সপোর্ট দৃষ্টান্ত আছে যা একটি সার্ভারের সাথে সংযুক্ত হয়ে গেলে, আপনি ডেটার বিচ্ছিন্ন বিট পাঠাতে এবং গ্রহণ করতে এটি ব্যবহার করতে পারেন, যা ডেটাগ্রাম নামে পরিচিত।
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);
}
স্ট্রিম API
আপনি একবার সার্ভারের সাথে সংযুক্ত হয়ে গেলে, আপনি ওয়েব ট্রান্সপোর্ট এর স্ট্রিম API এর মাধ্যমে ডেটা পাঠাতে এবং গ্রহণ করতে ব্যবহার করতে পারেন।
সমস্ত স্ট্রীমের প্রতিটি অংশ হল একটি Uint8Array
. Datagram API-এর বিপরীতে, এই স্ট্রিমগুলি নির্ভরযোগ্য। কিন্তু প্রতিটি স্ট্রীম স্বাধীন, তাই স্ট্রীম জুড়ে ডেটা অর্ডার নিশ্চিত নয়।
WebTransportSendStream
একটি 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
সার্ভার দ্বারা সূচিত হয়। একটি 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
আপনি একটি WebTransportBidirectionalStream
একটি WebTransport
দৃষ্টান্তের incomingBidirectionalStreams
বৈশিষ্ট্য সহ সার্ভার দ্বারা তৈরি করা শুনতে পারেন, যা একটি 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 খসড়া স্পেসিফিকেশনে সমস্ত পদ্ধতি এবং বৈশিষ্ট্যগুলির সম্পূর্ণ ডকুমেন্টেশন সহ বেশ কয়েকটি অতিরিক্ত ইনলাইন উদাহরণ রয়েছে।
Chrome এর DevTools-এ ওয়েব ট্রান্সপোর্ট
দুর্ভাগ্যবশত, Chrome এর DevTools বর্তমানে WebTransport সমর্থন করে না। আপনি DevTools ইন্টারফেসে আপডেট সম্পর্কে বিজ্ঞপ্তি পেতে এই Chrome সমস্যাটিকে "তারকা" করতে পারেন৷
পলিফিল
একটি পলিফিল (বা বরং পনিফিল যা আপনি ব্যবহার করতে পারেন এমন একটি স্বতন্ত্র মডিউল হিসাবে কার্যকারিতা প্রদান করে) যাকে বলা হয় webtransport-ponyfill-websocket
যা WebTransport-এর কিছু বৈশিষ্ট্য বাস্তবায়ন করে। এই সমাধানটি আপনার ব্যবহারের ক্ষেত্রে কাজ করতে পারে কিনা তা নির্ধারণ করতে প্রকল্পের README
এর সীমাবদ্ধতাগুলি সাবধানে পড়ুন।
গোপনীয়তা এবং নিরাপত্তা বিবেচনা
প্রামাণিক নির্দেশনার জন্য খসড়া স্পেসিফিকেশনের সংশ্লিষ্ট বিভাগটি দেখুন।
প্রতিক্রিয়া
Chrome টিম এই API ব্যবহার করে আপনার চিন্তাভাবনা এবং অভিজ্ঞতা শুনতে চায়৷
API ডিজাইন সম্পর্কে প্রতিক্রিয়া
API সম্পর্কে এমন কিছু আছে যা বিশ্রী বা প্রত্যাশিত হিসাবে কাজ করে না? অথবা আপনি আপনার ধারণা বাস্তবায়ন করতে হবে যে অনুপস্থিত টুকরা আছে?
ওয়েব ট্রান্সপোর্ট গিটহাব রেপোতে একটি সমস্যা ফাইল করুন, বা বিদ্যমান সমস্যাটিতে আপনার চিন্তা যোগ করুন।
বাস্তবায়নে সমস্যা?
আপনি কি Chrome এর বাস্তবায়নের সাথে একটি বাগ খুঁজে পেয়েছেন?
https://new.crbug.com এ একটি বাগ ফাইল করুন। পুনরুত্পাদনের জন্য সহজ নির্দেশাবলী সহ যতটা সম্ভব বিস্তারিত অন্তর্ভুক্ত করুন।
API ব্যবহার করার পরিকল্পনা করছেন?
আপনার সর্বজনীন সমর্থন Chrome কে বৈশিষ্ট্যগুলিকে অগ্রাধিকার দিতে সাহায্য করে এবং অন্যান্য ব্রাউজার বিক্রেতাদের দেখায় যে তাদের সমর্থন করা কতটা গুরুত্বপূর্ণ৷
- হ্যাশট্যাগ
#WebTransport
ব্যবহার করে @ChromiumDev- এ একটি টুইট পাঠান এবং কোথায় এবং কীভাবে আপনি এটি ব্যবহার করছেন তার বিশদ বিবরণ পাঠান।
সাধারণ আলোচনা
আপনি সাধারণ প্রশ্ন বা সমস্যাগুলির জন্য ওয়েব-ট্রান্সপোর্ট-ডেভ গুগল গ্রুপ ব্যবহার করতে পারেন যা অন্য কোনও বিভাগের সাথে খাপ খায় না।
স্বীকৃতি
এই নিবন্ধটি WebTransport Explainer , খসড়া স্পেসিফিকেশন , এবং সম্পর্কিত ডিজাইন ডক্স থেকে তথ্য অন্তর্ভুক্ত করে। সেই ভিত্তি প্রদানের জন্য সংশ্লিষ্ট লেখকদের ধন্যবাদ।
এই পোস্টে নায়কের ছবি আনস্প্ল্যাশে রবিন পিয়েরের ।