ویب ساکٹس (WebSockets) کیسے کام کرتے ہیں: ریئل ٹائم کنکشن کا تفصیلی جائزہ

ویب کے ابتدائی دنوں میں، براؤزر ایک سادہ دستاویز دیکھنے والا آلہ تھا۔ آپ ایک صفحے کی درخواست کرتے تھے، سرور اسے تیار کرتا تھا، اور کنکشن بند ہو جاتا تھا۔ یہ درخواست اور جواب کا چکر HTTP (Hypertext Transfer Protocol) کی بنیاد ہے۔

تاہم، جیسے جیسے ویب ایپلی کیشنز نے لائیو چیٹ، ریئل ٹائم مالیاتی ڈیٹا، دستاویزات پر مل کر کام کرنے، اور ملٹی پلیئر گیمز جیسے جدید تجربات کی شکل اختیار کی، تو روایتی HTTP ماڈل کی حدود ظاہر ہونے لگیں۔

لائیو اپ ڈیٹس حاصل کرنے کے لیے، ڈویلپرز نے شروع میں کچھ عارضی حل نکالے:

  • شارٹ پولنگ (Short Polling): براؤزر نئے ڈیٹا کی جانچ کرنے کے لیے ہر چند سیکنڈ میں سرور کو بار بار HTTP درخواستیں بھیجتا ہے۔ یہ ہیڈر کا بہت زیادہ بوجھ بناتا ہے اور سرور کے وسائل کو ضائع کرتا ہے۔
  • لانگ پولنگ (Long Polling / Comet): براؤزر ایک درخواست بھیجتا ہے، اور سرور نیا ڈیٹا دستیاب ہونے تک کنکشن کھلا رکھتا ہے۔ ڈیٹا بھیجے جانے کے بعد، کنکشن بند ہو جاتا ہے اور براؤزر فوری طور پر ایک نیا درخواست کھولتا ہے۔ یہ پیچیدہ ہے اور اس میں اب بھی کنکشن بنانے کے اخراجات زیادہ ہیں۔

ویب ساکٹس (WebSockets) نے ایک ہی TCP کنکشن پر مستقل، دو طرفہ (bi-directional)، اور فل ڈوپلیکس مواصلت کے لیے ایک معیاری پروٹوکول متعارف کروا کے ان مسائل کو حل کر دیا۔


ویب ساکٹ کیا ہے؟

ویب ساکٹس (جسے RFC 6455 میں بیان کیا گیا ہے) HTTP کے ساتھ کام کرتے ہیں۔ جہاں HTTP ایک سٹیٹ لیس (stateless) پروٹوکول ہے جس میں صرف کلائنٹ درخواست شروع کر سکتا ہے، وہیں ویب ساکٹ کنکشن ایک بار قائم ہونے کے بعد غیر معینہ مدت تک کھلا رہتا ہے، جس سے کلائنٹ اور سرور دونوں کسی بھی وقت ایک دوسرے کو بہت کم تاخیر (latency) کے ساتھ ڈیٹا بھیج سکتے ہیں۔

ویب ساکٹ کا بنیادی اصول یہ ہے:

ایک بار قائم ہونے کے بعد، کوئی بھی فریق نیا کنکشن درخواست شروع کیے بغیر کسی بھی وقت پیغام بھیج سکتا ہے۔


قدم بہ قدم کنکشن کا لائف سائیکل

ایک ویب ساکٹ کنکشن تین اہم مراحل سے گزرتا ہے: ہینڈ شیک (Handshake)، ڈیٹا کی منتقلی، اور کنکشن کا بند ہونا۔

WebSocket Connection Lifecycle Diagram

1. HTTP ہینڈ شیک (پروٹوکول اپ گریڈ)

چونکہ فائر والز اور راؤٹرز عام طور پر پورٹ 80 (HTTP) اور 443 (HTTPS) پر عام ویب ٹریفک کی اجازت دیتے ہیں، اس لیے ویب ساکٹس کا آغاز ایک معیاری HTTP/1.1 درخواست کے طور پر ہوتا ہے۔ اسے اپ گریڈ ہینڈ شیک کہا جاتا ہے۔

کلائنٹ کی درخواست

کلائنٹ پروٹوکول تبدیل کرنے کی درخواست کرنے والے مخصوص ہیڈرز کے ساتھ ایک HTTP GET درخواست بھیجتا ہے:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Origin: https://example.com
  • Upgrade: websocket اور Connection: Upgrade: سرور کو بتاتے ہیں کہ کلائنٹ پروٹوکول تبدیل کرنا چاہتا ہے۔
  • Sec-WebSocket-Key: بیس 64 میں انکوڈ شدہ ایک بے ترتیب 16 بائٹ ویلیو۔ یہ ثابت کرنے کے لیے استعمال ہوتی ہے کہ سرور کو ہینڈ شیک موصول ہوا ہے اور وہ ویب ساکٹ پروٹوکول کو سمجھتا ہے۔
  • Sec-WebSocket-Version: ویب ساکٹ پروٹوکول کا ورژن (عام طور پر 13) بتاتا ہے۔
  • Origin: سرور کے ذریعے یہ فیصلہ کرنے کے لیے استعمال کیا جاتا ہے کہ آیا کنکشن کی اجازت دی جائے یا نہیں (غیر مجاز سائٹس کے خلاف سیکیورٹی چیک)۔

سرور کا جواب

اگر سرور ویب ساکٹ کو سپورٹ کرتا ہے، تو وہ درخواست کی توثیق کرتا ہے اور HTTP اسٹیٹس کوڈ 101 Switching Protocols کے ساتھ جواب دیتا ہے:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  • سرور Sec-WebSocket-Accept کا حساب کیسے لگاتا ہے:
    1. سرور کلائنٹ کا Sec-WebSocket-Key (dGhlIHNhbXBsZSBub25jZQ==) لیتا ہے۔
    2. اسے ایک معیاری جادوئی GUID سٹرنگ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" کے ساتھ جوڑتا ہے۔
    3. جوڑے گئے سٹرنگ کا SHA-1 ہیش نکالتا ہے۔
    4. حاصل کردہ ہیش کو بیس 64 میں انکوڈ کرتا ہے۔
    5. اگر کلائنٹ تصدیق کرتا ہے کہ یہ ویلیو اس کی توقعات سے مطابقت رکھتی ہے، تو ہینڈ شیک کامیاب ہو جاتا ہے، HTTP کنکشن ایک خام TCP ساکٹ میں بدل جاتا ہے، اور دونوں فریق ویب ساکٹ پروٹوکول پر منتقل ہو جاتے ہیں۔

2. ڈیٹا فريمنگ اور منتقلی

HTTP کے برعکس، جو سادہ ٹیکسٹ ہیڈر اور اس کے بعد باڈی بھیجتا ہے، ویب ساکٹس ڈیٹا کو بائنری پیکٹوں میں منتقل کرتے ہیں جنہیں فریم (frames) کہا جاتا ہے۔

ایک ویب ساکٹ فریم میں ایک بہت ہی ہلکا ہیڈر (2 سے 14 بائٹس تک) ہوتا ہے، جس کے بعد پेलोڈ (ڈیٹا) ہوتا ہے۔ اس ہیڈر میں شامل ہیں:

  • FIN بٹ (1 بٹ): یہ ظاہر کرتا ہے کہ کیا یہ پیغام کا آخری فریم ہے۔
  • Opcode (4 بٹ): فریم کی قسم کی وضاحت کرتا ہے:
    • 0x1: ٹیکسٹ فریم (UTF-8 انکوڈ شدہ)
    • 0x2: بائنری فریم
    • 0x8: کنکشن بند کرنے کی درخواست
    • 0x9: پنگ (Ping)
    • 0xA: پونگ (Pong)
  • ماسک بٹ (1 بٹ): یہ بتاتا ہے کہ پेलोڈ ڈیٹا ماسک کیا گیا ہے یا نہیں۔
  • پيلوڈ کی لمبائی: ڈیٹا کا سائز۔
  • ماسکنگ کی (4 بائٹس): اہم سیکیورٹی ضرورت: کلائنٹ سے سرور پر بھیجے جانے والے تمام فریموں کو ایک بے ترتیب 4 بائٹ کی کا استعمال کرتے ہوئے ماسک (XOR طریقہ سے غیر واضح) کیا جانا چاہئے۔ یہ درمیانی پراکسیز کو ٹریفک پڑھنے یا کیشے زہر آلودگی کے حملوں سے روکتا ہے۔ سرور سے کلائنٹ کے فریم ماسک نہیں کیے جانے چاہئیں۔

ہارٹ بیٹ (پنگ/پونگ)

راؤٹرز اور لوڈ بیلنسرز کو غیر فعال کنکشن بند کرنے سے روکنے کے لیے، کوئی بھی فریق Ping فریم بھیج سکتا ہے۔ وصول کرنے والے فریق کو فوری طور پر اسی پेलोڈ والے Pong فریم کے ساتھ جواب دینا ہوگا۔

3. کنکشن بند کرنا

کنکشن کو صحیح طریقے سے بند کرنے کے لیے:

  1. ایک فریق ایک Close فریم بھیجتا ہے جس میں اسٹیٹس کوڈ (جیسے عام بند کے لیے 1000 اور غیر معمولی بند کے لیے 1006) اور ایک اختیاری تفصیل ہوتی ہے۔
  2. دوسرا فریق اپنے Close فریم کے ساتھ جواب دیتا ہے۔
  3. اندرونی TCP ساکٹ بند ہو جاتا ہے۔

کوڈ کی مثال: Node.js ویب ساکٹ کا نفاذ

ویب ساکٹس کو کام کرتے ہوئے دیکھنے کے لیے، آئیے ایک سادہ Node.js ایپلی کیشن لکھیں۔ ہم ایک مقامی ویب ساکٹ سرور بنائیں گے جو موصول ہونے والے کسی بھی پیغام کو واپس بھیجتا ہے، ساتھ ہی اس سے جڑنے کے لیے ایک کلائنٹ اسکرپٹ بھی بنائیں گے۔

ویب ساکٹ سرور (server.js)

const { WebSocketServer } = require('ws');
const http = require('http');

// 1. ایک معیاری HTTP سرور بنائیں
const server = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('HTTP Server running. Use WebSocket to connect.\n');
});

// 2. HTTP سرور سے ویب ساکٹ سرور جوڑیں
const wss = new WebSocketServer({ server });

wss.on('connection', (ws, req) => {
    const clientIp = req.socket.remoteAddress;
    console.log(`[سرور] نیا کلائنٹ جڑ گیا: ${clientIp}`);

    // کلائنٹ کو خوش آمدید کا پیغام بھیجیں
    ws.send(JSON.stringify({ type: 'welcome', message: 'غزنکس ویب ساکٹ سرور سے جڑ گئے!' }));

    // اس کلائنٹ سے آنے والے پیغامات کو سنیں
    ws.on('message', (message) => {
        console.log(`[سرور] موصولہ پیغام: ${message}`);
        
        try {
            const data = JSON.parse(message);
            ws.send(JSON.stringify({
                type: 'echo',
                message: `سرور کی بازگشت: ${data.text.toUpperCase()}`,
                timestamp: new Date().toISOString()
            }));
        } catch (e) {
            ws.send(JSON.stringify({ type: 'error', message: 'غیر موزوں JSON فارمیٹ' }));
        }
    });

    // کلائنٹ ڈسکنکشن کو سنبھالیں
    ws.on('close', (code, reason) => {
        console.log(`[سرور] کلائنٹ ڈسکنیکٹ ہو گیا (کوڈ: ${code}، وجہ: ${reason.toString() || 'کوئی نہیں'})`);
    });

    ws.on('error', (error) => {
        console.error(`[سرور] ساکٹ کی غلطی: ${error.message}`);
    });
});

server.listen(8080, () => {
    console.log('ویب ساکٹ سرور ws://localhost:8080 پر سن رہا ہے');
});

براؤزر کلائنٹ (کلائنٹ سائیڈ جاوا اسکرپٹ)

آپ اس کلائنٹ کو براہ راست اپنے براؤزر کے کنسول میں چلا سکتے ہیں:

// 1. سرور سے کنکشن قائم کریں
const socket = new WebSocket('ws://localhost:8080');

// 2. کنکشن کھلنے پر چلنے والا ہینڈلر
socket.addEventListener('open', (event) => {
    console.log('[کلائنٹ] سرور سے جڑ گیا ہے۔');
    
    const payload = JSON.stringify({ text: 'ہیلو سرور!' });
    socket.send(payload);
    console.log(`[کلائنٹ] بھیجا گیا: ${payload}`);
});

// 3. سرور سے آنے والے پیغامات کو سنیں
socket.addEventListener('message', (event) => {
    const response = JSON.parse(event.data);
    console.log('[کلائنٹ] سرور سے پیغام موصول ہوا:', response);
});

// 4. کنکشن بند ہونے کو سنیں
socket.addEventListener('close', (event) => {
    console.log(`[کلائنٹ] کنکشن بند ہو گیا (کوڈ: ${event.code})`);
});

// 5. غلطیوں کو سنیں
socket.addEventListener('error', (error) => {
    console.error('[کلائنٹ] ویب ساکٹ غلطی:', error);
});

HTTP بمقابلہ ویب ساکٹس: تفصیلی موازنہ

خصوصیت HTTP/1.1 ویب ساکٹس
مواصلت یک طرفہ (کلائنٹ شروع کرتا ہے) دو طرفہ (کلائنٹ یا سرور دونوں)
کنکشن ماڈل درخواست-جواب (عارضی) مستقل (طویل مدتی)
بوجھ (Overhead) زیادہ (ہر درخواست کے ساتھ ہیڈر بھیجے جاتے ہیں) بہت کم (کم سے کم فریم بوجھ)
سٹیٹ (State) سٹیٹ لیس سٹیٹ فل (کنکشن سیاق و سباق برقرار رہتا ہے)
پروٹوکول http:// یا https:// ws:// یا wss://
بہترین استعمال دستاویزات حاصل کرنا، REST APIs ریئل ٹائم چیٹ، ڈیش بورڈز، لائیو فیڈز

ویب ساکٹس کے لیے سیکیورٹی کے امور

چونکہ ویب ساکٹس ہینڈ شیک کے بعد عام HTTP روٹنگ کو بائی پاس کرتے ہیں، اس لیے وہ منفرد سیکیورٹی خطرات کا باعث بنتے ہیں:

  1. محفوظ ویب ساکٹ (wss://) کا استعمال کریں: ہمیشہ ویب ساکٹس کو TLS/SSL (پورٹ 443) پر چلائیں۔ WSS ڈیٹا کو انکرپٹ کرتا ہے، جس سے درمیان میں ڈیٹا چوری یا چھیڑ چھاڑ کو روکا جا سکے۔
  2. اوریجن کی توثیق (Origin Validation): ویب ساکٹس Same-Origin Policy کے پابند نہیں ہیں۔ غیر مجاز سائٹس کو کنکشن بنانے سے روکنے کے لیے ہینڈ شیک کے دوران سرور پر ہمیشہ Origin ہیڈر کی توثیق کریں۔
  3. ہینڈ شیک پر تصدیق (Authentication): کنکشن قائم ہونے سے پہلے صارفین کی تصدیق کریں۔ یہ عام طور پر کوئی ٹوکن (جیسے JWT) بھیج کر یا سیشن کوکیز کی تصدیق کر کے کیا جاتا ہے۔
  4. ان پٹ کی صفائی (Sanitization): ویب ساکٹس کے ذریعے موصول ہونے والے ہر پیغام کو ناقابل بھروسہ سمجھیں۔ کراس سائٹ اسکرپٹنگ (XSS) کو روکنے کے لیے ڈیٹا کی توثیق اور صفائی کریں۔

خلاصہ

ویب ساکٹس نے روایتی HTTP پولنگ کے بوجھ کو ختم کر کے ریئل ٹائم ویب ایپلی کیشنز میں انقلاب برپا کر دیا ہے۔ ایک ہی مستقل TCP کنکشن کو برقرار رکھ کر، یہ فوری دو طرفہ پیغامات بھیجنے کے قابل بناتا ہے، جو آج کے لائیو ڈیش بورڈز، آن لائن گیمز اور چیٹ ایپس کو طاقت دیتا ہے۔ HTTP اپ گریڈ، فریمنگ آرکیٹیکچر اور اہم سیکیورٹی طریقوں کو سمجھنا یہ یقینی بناتا ہے کہ آپ تیز رفتار اور محفوظ ریئل ٹائم سروسز بنائیں۔


غزنکس بلاگ پر مزید ڈویلپر گائیڈز اور ٹیٹوریلز دیکھیں →