সমস্যা: কম লেটেন্সি ক্লায়েন্ট-সার্ভার এবং সার্ভার-ক্লায়েন্ট কানেকশন
HTTP-এর তথাকথিত অনুরোধ/উত্তর প্যারাডাইমের উপর ভিত্তি করে মূলত ওয়েব তৈরি করা হয়েছে। কোনও ক্লায়েন্ট ওয়েব পেজ লোড করার পরে ব্যবহারকারী পরবর্তী পৃষ্ঠায় ক্লিক না করা পর্যন্ত আর কিছুই হয় না। ২০০৫ সালের কাছাকাছি সময়ে, AJAX ওয়েবকে আরও ডায়নামিক করে তুলতে শুরু করে। তবুও, সমস্ত HTTP কমিউনিকেশন ক্লায়েন্ট দ্বারা পরিচালিত হত, যার জন্য সার্ভার থেকে নতুন ডেটা লোড করার জন্য ব্যবহারকারীর ইন্টার্যাকশন বা পর্যায়ক্রমিক পোলিং প্রয়োজন ছিল।
সার্ভার যখনই জানতে পারে যে নতুন ডেটা উপলভ্য হয়েছে, তখনই ক্লায়েন্টকে ডেটা পাঠানোর প্রযুক্তি বেশ কিছুদিন ধরেই রয়েছে। এগুলি 'Push' বা 'Comet'-এর মতো নামে পরিচিত। সার্ভার থেকে শুরু করা কানেকশনের বিভ্রম তৈরি করার জন্য সবচেয়ে সাধারণ হ্যাকগুলির মধ্যে একটি হল লং পোলিং। লং পোলিংয়ের মাধ্যমে, ক্লায়েন্ট সার্ভারে একটি HTTP কানেকশন খোলে যা উত্তর না পাঠানো পর্যন্ত খোলা থাকে। সার্ভারে নতুন ডেটা থাকলে, এটি উত্তর পাঠায় (অন্যান্য টেকনিকের মধ্যে Flash, XHR মাল্টিপার্ট অনুরোধ এবং htmlfiles অন্তর্ভুক্ত)। লং পোলিং এবং অন্যান্য টেকনিক বেশ ভালো কাজ করে। আপনি প্রতিদিন Gmail চ্যাটের মতো অ্যাপ্লিকেশনে এগুলি ব্যবহার করেন।
তবে, এই সবকটি বিকল্পের ক্ষেত্রেই একটি সমস্যা রয়েছে: এগুলি HTTP-এর ওভারহেড বহন করে, যার ফলে কম লেটেন্সি অ্যাপ্লিকেশনের জন্য এগুলি উপযুক্ত নয়। ব্রাউজারে মাল্টিপ্লেয়ার ফার্স্ট পার্সন শুটার গেম বা রিয়েল-টাইম কম্পোনেন্ট সহ অন্য কোনও অনলাইন গেমের কথা ভাবুন।
WebSocket-এর সাথে পরিচয়: ওয়েবে সকেট নিয়ে আসা
WebSocket স্পেসিফিকেশন একটি API সংজ্ঞায়িত করে যা একটি ওয়েব ব্রাউজার এবং একটি সার্ভারের মধ্যে "সকেট" কানেকশন স্থাপন করে। সহজ কথায়: ক্লায়েন্ট ও সার্ভারের মধ্যে একটি স্থায়ী কানেকশন থাকে এবং যেকোনও পক্ষ যেকোনও সময় ডেটা পাঠানো শুরু করতে পারে।
শুরু করা
আপনি WebSocket কনস্ট্রাক্টর কল করে সহজেই একটি WebSocket কানেকশন খুলতে পারেন:
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
ws: লক্ষ্য করুন। এটি WebSocket কানেকশনের জন্য নতুন URL স্কিমা। এছাড়াও, সুরক্ষিত HTTP কানেকশনের জন্য যেভাবে https: ব্যবহার করা হয়, ঠিক সেইভাবেই সুরক্ষিত WebSocket কানেকশনের জন্য
wss: ব্যবহার করা হয়।
কানেকশনের সাথে সাথে কিছু ইভেন্ট হ্যান্ডলার অ্যাটাচ করলে, কানেকশন কখন খোলা হয়েছে, ইনকামিং মেসেজ কখন পাওয়া গেছে বা কোনও সমস্যা হয়েছে কিনা তা আপনি জানতে পারবেন।
দ্বিতীয় আর্গুমেন্ট ঐচ্ছিক সাব-প্রোটোকল গ্রহণ করে। এটি স্ট্রিং বা স্ট্রিংয়ের অ্যারে হতে পারে। প্রতিটি স্ট্রিং একটি সাব-প্রোটোকলের নাম উপস্থাপন করবে এবং সার্ভার অ্যারেতে পাস করা সাব-প্রোটোকলগুলির মধ্যে শুধুমাত্র একটি গ্রহণ করবে। WebSocket অবজেক্টের protocol প্রপার্টি অ্যাক্সেস করে গৃহীত সাব-প্রোটোকল নির্ধারণ করা যেতে পারে।
সাব-প্রোটোকলের নাম অবশ্যই IANA রেজিস্ট্রি-তে রেজিস্টার করা সাব-প্রোটোকলের নামের মধ্যে একটি হতে হবে। ফেব্রুয়ারি ২০১২ পর্যন্ত শুধুমাত্র একটি সাব-প্রোটোকল নাম (soap) রেজিস্টার করা আছে।
// When the connection is open, send some data to the server
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};
সার্ভারের সাথে কানেক্ট করা হচ্ছে
সার্ভারের সাথে কানেকশন তৈরি হওয়ার সাথে সাথেই (open ইভেন্ট শুরু হলে) আমরা কানেকশন অবজেক্টে send('your message') পদ্ধতি ব্যবহার করে সার্ভারে ডেটা পাঠানো শুরু করতে পারি। এটি আগে শুধু স্ট্রিং সাপোর্ট করত, কিন্তু লেটেস্ট স্পেসিফিকেশনে এটি এখন বাইনারি মেসেজও পাঠাতে পারে। বাইনারি ডেটা পাঠাতে, আপনি Blob অথবা ArrayBuffer অবজেক্ট ব্যবহার করতে পারবেন।
// Sending String
connection.send('your message');
// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
connection.send(binary.buffer);
// Sending file as Blob
var file = document.querySelector('input[type="file"]').files[0];
connection.send(file);
একইভাবে, সার্ভার যেকোনও সময় আমাদের মেসেজ পাঠাতে পারে। যখনই এটি ঘটে, onmessage কলব্যাক ফায়ার করে। কলব্যাক একটি ইভেন্ট অবজেক্ট পায় এবং আসল মেসেজটি data প্রপার্টির মাধ্যমে অ্যাক্সেস করা যায়।
WebSocket লেটেস্ট স্পেসিফিকেশনে বাইনারি মেসেজও রিসিভ করতে পারে। বাইনারি ফ্রেম Blob বা ArrayBuffer ফর্ম্যাটে রিসিভ করা যেতে পারে। প্রাপ্ত বাইনারির ফর্ম্যাট নির্দিষ্ট করতে, WebSocket অবজেক্টের binaryType প্রপার্টি 'blob' বা 'arraybuffer' হিসেবে সেট করুন। ডিফল্ট ফর্ম্যাট হল 'blob'। (পাঠানোর সময় আপনাকে binaryType প্যারাম অ্যালাইন করতে হবে না।)
// Setting binaryType to accept received binary as either 'blob' or 'arraybuffer'
connection.binaryType = 'arraybuffer';
connection.onmessage = function(e) {
console.log(e.data.byteLength); // ArrayBuffer object if binary
};
WebSocket-এ নতুন যোগ করা আরেকটি ফিচার হল এক্সটেনশন। এক্সটেনশন ব্যবহার করে, ফ্রেম কমপ্রেস, মাল্টিপ্লেক্স ইত্যাদি করা সম্ভব হবে। ওপেন ইভেন্টের পরে WebSocket অবজেক্টের এক্সটেনশন প্রপার্টি পরীক্ষা করে আপনি সার্ভার দ্বারা গৃহীত এক্সটেনশন খুঁজে পেতে পারেন। ফেব্রুয়ারি ২০১২ পর্যন্ত অফিসিয়ালি প্রকাশিত কোনও এক্সটেনশন স্পেসিফিকেশন নেই।
// Determining accepted extensions
console.log(connection.extensions);
ক্রস-অরিজিন কমিউনিকেশন
আধুনিক প্রোটোকল হওয়ার কারণে, ক্রস অরিজিন কমিউনিকেশন WebSocket-এর মধ্যেই থাকে। আপনি এখনও শুধুমাত্র বিশ্বস্ত ক্লায়েন্ট এবং সার্ভারের সাথে যোগাযোগ করছেন কিনা তা নিশ্চিত করা উচিত, WebSocket যেকোনও ডোমেনে পার্টিদের মধ্যে যোগাযোগ সক্ষম করে। সার্ভার সিদ্ধান্ত নেয় যে তার পরিষেবা সব ক্লায়েন্টকে উপলভ্য করবে নাকি শুধু তাদের যারা সুনির্দিষ্ট ডোমেনের সেটে থাকে।
প্রক্সি সার্ভার
প্রতিটি নতুন প্রযুক্তির সাথে নতুন সমস্যাও আসে। WebSocket-এর ক্ষেত্রে এটি হল প্রক্সি সার্ভারের সাথে মানানসই হওয়া যা বেশিরভাগ কোম্পানির নেটওয়ার্কে HTTP কানেকশন মধ্যস্থতা করে। WebSocket প্রোটোকল HTTP কানেকশনকে WebSocket কানেকশনে 'আপগ্রেড' করতে HTTP আপগ্রেড সিস্টেম (যা সাধারণত HTTP/SSL-এর জন্য ব্যবহার করা হয়) ব্যবহার করে। কিছু প্রক্সি সার্ভার এটি পছন্দ করে না এবং কানেকশন ড্রপ করে দেয়। তাই, কোনও ক্লায়েন্ট WebSocket প্রোটোকল ব্যবহার করলেও, কানেকশন তৈরি করা সম্ভব নাও হতে পারে। এর ফলে পরবর্তী বিভাগটি আরও গুরুত্বপূর্ণ হয়ে ওঠে :)
আজই WebSockets ব্যবহার করুন
WebSocket এখনও একটি নতুন প্রযুক্তি এবং সব ব্রাউজারে সম্পূর্ণভাবে প্রয়োগ করা হয়নি। তবে, আপনি আজই WebSocket ব্যবহার করতে পারেন এমন লাইব্রেরির সাথে যা উপরে উল্লিখিত ফলব্যাকগুলির মধ্যে একটি ব্যবহার করে যখনই WebSocket উপলভ্য থাকে না। এই ডোমেনে খুব জনপ্রিয় হয়ে ওঠা একটি লাইব্রেরি হল socket.io যা প্রোটোকলের ক্লায়েন্ট ও সার্ভার ইমপ্লিমেন্টেশন সহ আসে এবং এতে ফলব্যাক অন্তর্ভুক্ত থাকে (ফেব্রুয়ারি ২০১২ পর্যন্ত socket.io বাইনারি মেসেজিং সাপোর্ট করে না)। এছাড়াও, PusherApp-এর মতো বাণিজ্যিক সমাধান আছে যা ক্লায়েন্টদের WebSocket মেসেজ পাঠানোর জন্য HTTP API প্রদান করে যেকোনও ওয়েব এনভায়রনমেন্টে সহজেই ইন্টিগ্রেট করা যায়। অতিরিক্ত HTTP অনুরোধের কারণে, পিওর WebSocket-এর তুলনায় সবসময় অতিরিক্ত ওভারহেড থাকবে।
সার্ভার সাইড
WebSocket ব্যবহার করলে সার্ভার সাইড অ্যাপ্লিকেশনের জন্য সম্পূর্ণ নতুন ব্যবহারের প্যাটার্ন তৈরি হয়। LAMP-এর মতো প্রথাগত সার্ভার স্ট্যাক HTTP অনুরোধ/প্রতিক্রিয়া চক্রের উপর ভিত্তি করে ডিজাইন করা হলেও, অনেক সময় সেগুলি বিপুল সংখ্যক ওপেন WebSocket কানেকশন সামলাতে পারে না। একই সময়ে অনেক কানেকশন খোলা রাখার জন্য এমন আর্কিটেকচার প্রয়োজন যা কম পারফর্ম্যান্স খরচে অনেক বেশি কনকারেন্সি পায়। এই ধরনের আর্কিটেকচার সাধারণত থ্রেডিং বা তথাকথিত নন-ব্লকিং IO-এর উপর ভিত্তি করে ডিজাইন করা হয়।
সার্ভার সাইড ইমপ্লিমেন্টেশন
- Node.js
- Java
- Ruby
- Python
- Erlang
- C++
- .NET
প্রোটোকল ভার্সন
WebSocket-এর জন্য ওয়্যার প্রোটোকল (ক্লায়েন্ট ও সার্ভারের মধ্যে হ্যান্ডশেক ও ডেটা ট্রান্সফার) এখন RFC6455। Android-এর জন্য লেটেস্ট Chrome এবং Chrome, বাইনারি মেসেজিং সহ RFC6455-এর সাথে সম্পূর্ণ মানানসই। এছাড়াও, Firefox-এর ১১ ভার্সন ও Internet Explorer-এর ১০ ভার্সনে এটি কাজ করবে। আপনি এখনও পুরনো প্রোটোকল ভার্সন ব্যবহার করতে পারেন তবে এটি সাজেস্ট করা হয় না কারণ সেগুলি সুরক্ষিত নয় বলে জানা গেছে। WebSocket প্রোটোকলের পুরনো ভার্সনের জন্য আপনার সার্ভার ইমপ্লিমেন্টেশন থাকলে, আমরা আপনাকে এটি লেটেস্ট ভার্সনে আপগ্রেড করার সাজেশন দিই।
যেসব ক্ষেত্রে ব্যবহার করা যাবে
ক্লায়েন্ট ও সার্ভারের মধ্যে যখনই আপনার খুব কম লেটেন্সি, প্রায় রিয়েল-টাইম কানেকশন প্রয়োজন হবে, তখনই WebSocket ব্যবহার করুন। মনে রাখবেন যে এর জন্য আপনাকে হয়ত সার্ভার সাইড অ্যাপ্লিকেশন তৈরির পদ্ধতি নিয়ে নতুন করে ভাবতে হবে এবং ইভেন্ট কিউয়ের মতো প্রযুক্তির উপর নতুন করে ফোকাস করতে হবে। ব্যবহারের কিছু উদাহরণ হল:
- মাল্টিপ্লেয়ার অনলাইন গেম
- চ্যাট অ্যাপ্লিকেশন
- লাইভ স্পোর্টস টিকার
- রিয়েল-টাইমে সোশ্যাল স্ট্রিম আপডেট করা হচ্ছে
ডেমো
- Plink
- আমার সাথে আঁকো
- Pixelatr
- ড্যাশ করা
- ম্যাসিভলি মাল্টিপ্লেয়ার অনলাইন ক্রসওয়ার্ড
- পিং সার্ভার (উপরের উদাহরণে ব্যবহার করা হয়েছে)
- HTML5demos স্যাম্পেল