HTTP2 moduli


ULASHISH

HTTP/2 nima?

Node.js HTTP/2 moduli HTTP/2 protokolini amalga oshirishni ta’minlaydi, u yaxshilangan ishlash, serverni surish imkoniyatlari, sarlavhalarni siqish va bitta ulanish orqali multiplekslashni taklif qiladi.

HTTP/2 bir nechta asosiy xususiyatlarga ega HTTP/1.1 ni yaxshilaydi:

  • Ikkilik protokoli: HTTP/2 ma’lumotlarni uzatish uchun HTTP/1.1 matn formatidan ko‘ra ikkilik formatdan foydalanadi, bu uni tahlil qilishni samaraliroq qiladi.
  • Multiplexing: Bir vaqtning o‘zida bir nechta so‘rovlar va javoblar bitta ulanish orqali yuborilishi mumkin.
  • Sarlavhani siqish: HTTP/2 yukni kamaytirish uchun sarlavhalarni siqib chiqaradi.
  • Server push: Serverlar mijozlar so‘rashidan oldin resurslarni faol ravishda yuborishlari mumkin.
  • Stream ustuvorligi: Resurslar turli ustuvorliklar bilan yetkazib berilishi mumkin.

HTTP/2 modulidan foydalanish

Node.js da HTTP/2 moduliga quyidagilar yordamida kirish mumkin:

const http2 = require('http2');

HTTP/2 moduli Node.js v10.0.0 dan boshlab barqaror. Shuni ta’kidlash kerakki, HTTP/2 ko‘pgina brauzerlarda xavfsiz ulanishni (HTTPS) talab qiladi, shuning uchun ko‘pchilik misollarda TLS/SSL ishlatiladi.


HTTP/2 serverini yaratish

TLS yordamida asosiy HTTP/2 serverini yaratish misoli:

const http2 = require('http2');
const fs = require('fs');
const path = require('path');

// Read the TLS certificate and key
const options = {
  key: fs.readFileSync(path.join(__dirname, 'server.key')),
  cert: fs.readFileSync(path.join(__dirname, 'server.crt'))
};

// Create an HTTP/2 server
const server = http2.createSecureServer(options);

// Handle stream events
server.on('stream', (stream, headers) => {
  // Get the path from headers
  const path = headers[':path'];
  
  // Send a response
  if (path === '/') {
    stream.respond({
      'content-type': 'text/html',
      ':status': 200
    });
    stream.end('<h1>Hello from HTTP/2!</h1>');
  } else {
    stream.respond({
      ':status': 404
    });
    stream.end('Not found');
  }
});

// Start the server
const port = 8080;
server.listen(port, () => {
  console.log(`HTTP/2 server running at https://localhost:${port}`);
});

Ushbu misol sizda TLS sertifikat fayllari mavjudligini nazarda tutadi. Rivojlanish uchun siz OpenSSL yordamida o‘z-o‘zidan imzolangan sertifikatlarni yaratishingiz mumkin. Ishlab chiqarish uchun ishonchli sertifikat organidan foydalaning.

Shuningdek, siz HTTP/2 serverini TLSsiz yaratishingiz mumkin (shifrlashsiz to‘g‘ridan-to‘g‘ri HTTP/2 ulanishlari uchun):

const http2 = require('http2');

// Create an HTTP/2 server without TLS
const server = http2.createServer();

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });
  stream.end('<h1>Hello from HTTP/2 without TLS!</h1>');
});

server.listen(8080);

Aksariyat zamonaviy brauzerlar faqat TLS orqali HTTP/2 ni qo‘llab-quvvatlaydi, shuning uchun xavfsiz bo‘lmagan HTTP/2 serveri odatda faqat HTTP/2 aniq matnni qo‘llab-quvvatlaydigan maxsus HTTP/2 mijozlari bilan ishlaydi.



HTTP/2 mijozi

HTTP/2 serveriga ulanish uchun HTTP/2 mijozini yaratish:

const http2 = require('http2');

// Create a client
const client = http2.connect('https://localhost:8080', {
  // For self-signed certificates in development
  rejectUnauthorized: false
});

// Error handling
client.on('error', (err) => {
  console.error('Client error:', err);
});

// Create a request
const req = client.request({ ':path': '/' });

// Handle response data
req.on('response', (headers) => {
  console.log('Status:', headers[':status']);
  console.log('Headers:', headers);
});

req.on('data', (chunk) => {
  console.log('Received data:', chunk.toString());
});

req.on('end', () => {
  console.log('Request completed');
  client.close();
});

// Send the request
req.end();

HTTP/2 oqimlari

HTTP/2 mijoz va server o‘rtasidagi aloqa uchun oqimlardan foydalanadi. Har bir stream mijoz va server o‘rtasida almashinadigan mustaqil, ikki yo‘nalishli frameworklar ketma-ketligini ifodalaydi.

Oqimli voqealar

Muhim stream voqealariga quyidagilar kiradi:

  • 'headers' : Sarlavhalar qabul qilinganda chiqariladi
  • 'data' : Ma’lumotlarning bir qismi qabul qilinganda chiqariladi
  • 'end' : Stream tugagach chiqariladi
  • 'error' : Xatolik yuz berganda chiqariladi
const http2 = require('http2');
const fs = require('fs');
const path = require('path');

// Create a server
const server = http2.createSecureServer({
  key: fs.readFileSync(path.join(__dirname, 'server.key')),
  cert: fs.readFileSync(path.join(__dirname, 'server.crt'))
});

server.on('stream', (stream, headers) => {
  // Handle stream events
  stream.on('error', (error) => {
    console.error('Stream error:', error);
  });
  
  stream.on('close', () => {
    console.log('Stream closed');
  });
  
  // Handle request
  stream.respond({
    'content-type': 'text/plain',
    ':status': 200
  });
  
  // Send data in multiple chunks
  stream.write('First chunk of data\n');
  
  setTimeout(() => {
    stream.write('Second chunk of data\n');
    stream.end('Final chunk of data');
  }, 1000);
});

server.listen(8080);

HTTP/2 Server Push

Serverni surish serverga resurslarni mijozga aniq so‘ralishidan oldin faol ravishda yuborish imkonini beradi. Bu ikki safarda kechikishlarni bartaraf etish orqali ishlashni yaxshilashi mumkin.

const http2 = require('http2');
const fs = require('fs');
const path = require('path');

const options = {
  key: fs.readFileSync(path.join(__dirname, 'server.key')),
  cert: fs.readFileSync(path.join(__dirname, 'server.crt'))
};

const server = http2.createSecureServer(options);

server.on('stream', (stream, headers) => {
  const requestPath = headers[':path'];
  
  if (requestPath === '/') {
    // Push CSS and JavaScript resources
    stream.pushStream({ ':path': '/style.css' }, (err, pushStream) => {
      if (err) {
        console.error('Error pushing stream:', err);
        return;
      }
      
      pushStream.respond({
        'content-type': 'text/css',
        ':status': 200
      });
      
      pushStream.end('body { color: blue; }');
    });
    
    stream.pushStream({ ':path': '/script.js' }, (err, pushStream) => {
      if (err) {
        console.error('Error pushing stream:', err);
        return;
      }
      
      pushStream.respond({
        'content-type': 'application/javascript',
        ':status': 200
      });
      
      pushStream.end('console.log("Hello from HTTP/2 server push!");');
    });
    
    // Send the main HTML document
    stream.respond({
      'content-type': 'text/html',
      ':status': 200
    });
    
    stream.end(`
      <!DOCTYPE html>
      <html>
      <head>
        <title>HTTP/2 Server Push Example</title>
        <link rel="stylesheet" href="/style.css">
        <script src="/script.js"></script>
      </head>
      <body>
        <h1>HTTP/2 Server Push Demo</h1>
        <p>CSS and JavaScript were pushed by the server!</p>
      </body>
    </html>
    `);
  } else {
    // Serve pushed resources if requested directly
    if (requestPath === '/style.css') {
      stream.respond({
        'content-type': 'text/css',
        ':status': 200
      });
      stream.end('body { color: blue; }');
    } else if (requestPath === '/script.js') {
      stream.respond({
        'content-type': 'application/javascript',
        ':status': 200
      });
      stream.end('console.log("Hello from HTTP/2 server push!");');
    } else {
      // Not found
      stream.respond({ ':status': 404 });
      stream.end('Not found');
    }
  }
});

server.listen(8080);

HTTP/2 sarlavhalari

HTTP/2 sarlavhalar uchun boshqa formatdan foydalanadi. Shunisi e’tiborga loyiqki, barcha sarlavhalar kichik harflar va so‘rovning soxta sarlavhalari ikki nuqta (:) bilan boshlanadi.

const http2 = require('http2');

// HTTP/2 pseudo-headers
const {
  HTTP2_HEADER_METHOD,
  HTTP2_HEADER_PATH,
  HTTP2_HEADER_AUTHORITY,
  HTTP2_HEADER_SCHEME,
  HTTP2_HEADER_STATUS
} = http2.constants;

// Create a client
const client = http2.connect('https://localhost:8080', {
  rejectUnauthorized: false
});

// Send a request with custom headers
const req = client.request({
  [HTTP2_HEADER_METHOD]: 'GET',
  [HTTP2_HEADER_PATH]: '/',
  [HTTP2_HEADER_AUTHORITY]: 'localhost:8080',
  [HTTP2_HEADER_SCHEME]: 'https',
  'user-agent': 'node-http2/client',
  'custom-header': 'custom-value'
});

req.on('response', (headers) => {
  console.log('Response status:', headers[HTTP2_HEADER_STATUS]);
  console.log('Response headers:', headers);
});

req.on('data', (chunk) => {
  console.log('Received data:', chunk.toString());
});

req.on('end', () => {
  client.close();
});

req.end();

HTTP/2 sozlamalari

HTTP/2 turli xil protokol sozlamalarini sozlash imkonini beradi:

const http2 = require('http2');
const fs = require('fs');
const path = require('path');

const options = {
  key: fs.readFileSync(path.join(__dirname, 'server.key')),
  cert: fs.readFileSync(path.join(__dirname, 'server.crt')),
  
  // HTTP/2 settings
  settings: {
    // Max concurrent streams per connection
    maxConcurrentStreams: 100,
    
    // Initial window size for flow control
    initialWindowSize: 1024 * 1024, // 1MB
    
    // Enable server push
    enablePush: true
  }
};

const server = http2.createSecureServer(options);

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });
  
  stream.end('<h1>HTTP/2 Server with Custom Settings</h1>');
});

server.listen(8080);

HTTP/1.1 bilan moslik

HTTP/2 serverlari uzluksiz yangilanish yo‘lini ta’minlovchi HTTP/1.1 so‘rovlarini ham bajarishi mumkin:

const http2 = require('http2');
const http = require('http');
const fs = require('fs');
const path = require('path');

// For HTTP/2 secure server
const options = {
  key: fs.readFileSync(path.join(__dirname, 'server.key')),
  cert: fs.readFileSync(path.join(__dirname, 'server.crt')),
  allowHTTP1: true // Allow HTTP/1.1 connections
};

const server = http2.createSecureServer(options);

// Handler function for both HTTP/1.1 and HTTP/2
const handler = (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end(`Hello from ${req.httpVersion} server!`);
};

// HTTP/1.1 compatibility request handler
server.on('request', handler);

// HTTP/2 specific stream handler
server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/plain',
    ':status': 200
  });
  stream.end(`Hello from HTTP/2 stream API!`);
});

server.listen(8080, () => {
  console.log('Server running at https://localhost:8080/');
});

Ishlash bo‘yicha mulohazalar

HTTP/2 unumdorlikni yaxshilashni taklif qilsa-da, foydalanishni optimallashtirish muhim:

  1. Ulanishni qayta ishlatish - HTTP/2 bilan siz yangi ulanishlar yaratish o‘rniga bir nechta so‘rovlar uchun bitta ulanishdan foydalanishni maqsad qilishingiz kerak.
  2. Oqimlarni to‘g‘ri boshqarish - Streamlar kerak bo‘lmaganda ularni yopishni unutmang va bir vaqtda streamlar sonini kuzatib boring.
  3. Server Push strategiyasi - Faqat kerak bo‘lishi mumkin bo‘lgan resurslarni surish. Haddan tashqari surish tarmoqli kengligi va resurslarni behuda sarflashi mumkin.
  4. Sarlavhalarni siqish - Maxsus sarlavhalar soni va hajmini minimallashtirish orqali HTTP/2 sarlavhalarini siqish imkoniyatlaridan foydalaning.

HTTP/2 va HTTP/1.1

HTTP/2 va HTTP/1.1 o‘rtasidagi asosiy farqlar:

Xususiyat HTTP/1.1 HTTP/2
Protokol formati Matnga asoslangan Ikkilik asosli
Multiplekslash No (requires multiple connections) Ha (bitta ulanish orqali bir nechta oqim)
Sarlavhani siqish Yo‘q Yes (HPACK)
Server Push Yo‘q Ha
Stream nazorati Asosiy Kengaytirilgan, har bir stream
Ustuvorlik Yo‘q Ha

Haqiqiy dunyo misoli: to‘liq veb-saytga xizmat ko‘rsatish

HTTP/2 bilan veb-saytga xizmat ko‘rsatishning to‘liq namunasi:

const http2 = require('http2');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');

const options = {
  key: fs.readFileSync(path.join(__dirname, 'server.key')),
  cert: fs.readFileSync(path.join(__dirname, 'server.crt'))
};

const server = http2.createSecureServer(options);

// Serve files from the public directory
const publicDir = path.join(__dirname, 'public');

server.on('stream', (stream, headers) => {
  const reqPath = headers[':path'] === '/' ? '/index.html' : headers[':path'];
  const filePath = path.join(publicDir, reqPath);
  
  // Basic security check to prevent path traversal
  if (!filePath.startsWith(publicDir)) {
    stream.respond({ ':status': 403 });
    stream.end('Forbidden');
    return;
  }
  
  fs.stat(filePath, (err, stats) => {
    if (err || !stats.isFile()) {
      // File not found
      stream.respond({ ':status': 404 });
      stream.end('Not found');
      return;
    }
    
    // Determine content type
    const contentType = mime.lookup(filePath) || 'application/octet-stream';
    
    // Serve the file
    stream.respond({
      'content-type': contentType,
      ':status': 200
    });
    
    const fileStream = fs.createReadStream(filePath);
    fileStream.pipe(stream);
    
    fileStream.on('error', (err) => {
      console.error('File stream error:', err);
      stream.close(http2.constants.NGHTTP2_INTERNAL_ERROR);
    });
  });
});

server.listen(8080, () => {
  console.log('HTTP/2 server running at https://localhost:8080/');
});

Ushbu misol mime-types paketini talab qiladi:

npm install mime-types

Kengaytirilgan stream boshqaruvi

HTTP/2 ning oqimlarni boshqarish imkoniyatlari bir vaqtning o‘zida bir nechta so‘rovlarni samarali boshqarish imkonini beradi. Mana, stream ustuvorligi va oqimni boshqarishni ko‘rsatadigan ilg‘or misol:

const http2 = require('http2');
const fs = require('fs');

// Create a server with custom settings
const server = http2.createSecureServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt'),
  settings: {
    initialWindowSize: 65535,  // 64KB initial window
    maxConcurrentStreams: 100,
    enablePush: true
  }
});

server.on('stream', (stream, headers) => {
  // Get priority information
  const weight = stream.priority && stream.priority.weight || 1;
  const parent = stream.priority && stream.priority.parent ? 'with parent' : 'no parent';
  
  console.log(`New stream ${stream.id} (weight: ${weight}, ${parent})`);
  
  // Handle different priority levels
  if (headers[':path'] === '/high-priority') {
    stream.priority({ weight: 256, exclusive: true });
    stream.respond({ ':status': 200, 'content-type': 'text/plain' });
    stream.end('High priority content');
  } else {
    // Default priority
    stream.respond({ ':status': 200, 'content-type': 'text/plain' });
    stream.end('Standard priority content');
  }
  
  // Handle stream errors
  stream.on('error', (error) => {
    console.error(`Stream ${stream.id} error:`, error);
    stream.end();
  });
  
  // Handle stream close
  stream.on('close', () => {
    console.log(`Stream ${stream.id} closed`);
  });
});

server.listen(8443);

Xatolarni qayta ishlash va debug

Ishonchli HTTP/2 ilovalari uchun xatolarni to‘g‘ri hal qilish juda muhimdir. Xatolarni keng qamrovli hal qilishni qanday amalga oshirish mumkin:

const http2 = require('http2');
const fs = require('fs');
const { promisify } = require('util');
const readFile = promisify(fs.readFile);

async function startServer() {
  try {
    const [key, cert] = await Promise.all([
      readFile('server.key'),
      readFile('server.crt')
    ]);

    const server = http2.createSecureServer({ key, cert });
    
    // Global error handler
    server.on('error', (err) => {
      console.error('Server error:', err);
      // Implement proper error recovery
    });
    
    // Handle uncaught exceptions
    process.on('uncaughtException', (err) => {
      console.error('Uncaught exception:', err);
      // Graceful shutdown
      server.close(() => process.exit(1));
    });
    
    // Handle unhandled promise rejections
    process.on('unhandledRejection', (reason, promise) => {
      console.error('Unhandled Rejection at:', promise, 'reason:', reason);
    });
    
    // Stream handler with error boundaries
    server.on('stream', (stream, headers) => {
      try {
        // Simulate async operation
        setTimeout(() => {
          try {
            if (Math.random() > 0.8) {
              throw new Error('Random error for demonstration');
            }
            stream.respond({ ':status': 200 });
            stream.end('Success!');
          } catch (err) {
            handleStreamError(stream, err);
          }
        }, 100);
      } catch (err) {
        handleStreamError(stream, err);
      }
    });
    
    function handleStreamError(stream, error) {
      console.error('Stream error:', error);
      if (!stream.destroyed) {
        stream.respond({
          ':status': 500,
          'content-type': 'text/plain'
        });
        stream.end('Internal Server Error');
      }
    }
    
    server.listen(8443, () => {
      console.log('Server running on https://localhost:8443');
    });
    
  } catch (err) {
    console.error('Failed to start server:', err);
    process.exit(1);
  }
}

startServer();

Ishlashni optimallashtirish

HTTP/2 ishlashini optimallashtirish uning o‘ziga xos xususiyatlarini tushunishni talab qiladi. Bu yerda asosiy strategiyalar:

1. Ulanishni birlashtirish

const http2 = require('http2');
const { URL } = require('url');

class HTTP2ConnectionPool {
  constructor() {
    this.connections = new Map();
  }
  
  async getConnection(url) {
    const { origin } = new URL(url);
    
    if (!this.connections.has(origin)) {
      const client = http2.connect(origin, {
        rejectUnauthorized: false // Only for development
      });
      
      // Handle connection errors
      client.on('error', (err) => {
        console.error('Connection error:', err);
        this.connections.delete(origin);
      });
      
      // Remove connection when closed
      client.on('close', () => {
        this.connections.delete(origin);
      });
      
      this.connections.set(origin, {
        client,
        lastUsed: Date.now(),
        inUse: 0
      });
    }
    
    const conn = this.connections.get(origin);
    conn.lastUsed = Date.now();
    conn.inUse++;
    
    return {
      client: conn.client,
      release: () => {
        conn.inUse--;
      }
    };
  }
  
  // Clean up idle connections
  startCleanup(interval = 30000) {
    setInterval(() => {
      const now = Date.now();
      for (const [origin, conn] of this.connections.entries()) {
        if (conn.inUse === 0 && (now - conn.lastUsed) > 60000) {
          conn.client.destroy();
          this.connections.delete(origin);
        }
      }
    }, interval);
  }
}

// Usage example
const pool = new HTTP2ConnectionPool();
pool.startCleanup();

async function makeRequest(url) {
  const { client, release } = await pool.getConnection(url);
  return new Promise((resolve, reject) => {
    const req = client.request({ ':path': new URL(url).pathname });
    let data = '';
    
    req.on('response', (headers) => {
      console.log('Status:', headers[':status']);
    });
    
    req.on('data', (chunk) => data += chunk);
    req.on('end', () => {
      release();
      resolve(data);
    });
    req.on('error', (err) => {
      release();
      reject(err);
    });
    
    req.end();
  });
}

2. Sarlavhani siqishni optimallashtirish

HTTP/2 sarlavhalar uchun HPACK siqishni ishlatadi. Optimallashtirish:

  • Cookie o‘lchamlarini minimallashtirish
  • Qisqa, ammo tavsiflovchi sarlavha nomlaridan foydalanish
  • Ikki nusxadagi sarlavhalardan qochish
  • Mumkin bo‘lganda HTTP/2-ga xos sarlavhalardan foydalanish

Xavfsizlik bo‘yicha eng yaxshi amaliyotlar

HTTP/2 dan foydalanayotganda quyidagi xavfsizlik amaliyotlariga amal qiling:

const http2 = require('http2');
const fs = require('fs');
const { createSecureContext } = require('tls');

// Security headers middleware
function securityHeaders(req, res, next) {
  // Set security headers
  res.setHeader('X-Content-Type-Options', 'nosniff');
  res.setHeader('X-Frame-Options', 'DENY');
  res.setHeader('X-XSS-Protection', '1; mode=block');
  res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
  res.setHeader('Content-Security-Policy', "default-src 'self'");
  
  // Remove server header
  res.removeHeader('X-Powered-By');
  
  next();
}

// Create secure server with modern TLS settings
const options = {
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt'),
  secureOptions:
    require('constants').SSL_OP_NO_SSLv3 |
    require('constants').SSL_OP_NO_TLSv1 |
    require('constants').SSL_OP_NO_TLSv1_1,
  ciphers: [
    'TLS_AES_256_GCM_SHA384',
    'TLS_CHACHA20_POLY1305_SHA256',
    'TLS_AES_128_GCM_SHA256'
  ].join(':'),
  minVersion: 'TLSv1.3',
  maxVersion: 'TLSv1.3',
  // OCSP Stapling
  requestCert: false,
  rejectUnauthorized: true
};

const server = http2.createSecureServer(options);

// Apply security middleware
server.on('request', (req, res) => {
  securityHeaders(req, res, () => {
    // Request handling logic
    res.setHeader('Content-Type', 'text/plain');
    res.end('Secure HTTP/2 Response');
  });
});

// Handle TLS errors
server.on('tlsClientError', (err, tlsSocket) => {
  console.error('TLS Error:', err);
  tlsSocket.destroy();
});

server.listen(8443);

Haqiqiy foydalanish holatlari

1. HTTP/2 bilan API shlyuzi

HTTP/2 bilan yuqori samarali API shlyuzini yaratish:

const http2 = require('http2');
const { URL } = require('url');
const path = require('path');
const fs = require('fs');

// Service registry
const services = {
  '/users': 'http://users-service:3000',
  '/products': 'http://products-service:3000',
  '/orders': 'http://orders-service:3000'
};

// Create HTTP/2 server
const server = http2.createSecureServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt')
});

// Route requests to appropriate services
server.on('stream', (stream, headers) => {
  const path = headers[':path'];
  const method = headers[':method'];
  
  try {
    // Find matching service
    const servicePath = Object.keys(services).find(prefix =>
      path.startsWith(prefix)
    );
    
    if (!servicePath) {
      stream.respond({ ':status': 404 });
      return stream.end('Not Found');
    }
    
    const targetUrl = new URL(path.slice(servicePath.length), services[servicePath]);
    
    // Forward request to target service
    const client = http2.connect(targetUrl.origin);
    const req = client.request({
      ...headers,
      ':path': targetUrl.pathname + targetUrl.search,
      ':method': method,
      ':authority': targetUrl.host
    });
    
    // Pipe the response back to client
    req.pipe(stream);
    stream.pipe(req);
    
    // Handle errors
    req.on('error', (err) => {
      console.error('Request error:', err);
      if (!stream.destroyed) {
        stream.respond({ ':status': 502 });
        stream.end('Bad Gateway');
      }
    });
    
    stream.on('error', (err) => {
      console.error('Stream error:', err);
      req.destroy();
    });
    
  } catch (err) {
    console.error('Gateway error:', err);
    if (!stream.destroyed) {
      stream.respond({ ':status': 500 });
      stream.end('Internal Server Error');
    }
  }
});

server.listen(443);

2. Real vaqt rejimida ma’lumotlarni uzatish

HTTP/2 bilan real vaqtda samarali ma’lumotlarni uzatish:

const http2 = require('http2');
const fs = require('fs');

const server = http2.createSecureServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt')
});

// In-memory storage for active streams
const streams = new Set();

// Broadcast data to all connected clients
function broadcast(data) {
  const payload = JSON.stringify(data);
  for (const stream of streams) {
    try {
      stream.write(`data: ${payload}\n\n`);
    } catch (err) {
      console.error('Stream write error:', err);
      streams.delete(stream);
    }
  }
}

// Simulate data updates
setInterval(() => {
  broadcast({
    time: new Date().toISOString(),
    value: Math.random() * 100
  });
}, 1000);

server.on('stream', (stream, headers) => {
  // Only handle GET requests
  if (headers[':method'] !== 'GET') {
    stream.respond({ ':status': 405 });
    return stream.end();
  }
  
  // Set up Server-Sent Events headers
  stream.respond({
    'content-type': 'text/event-stream',
    'cache-control': 'no-cache',
    'connection': 'keep-alive',
    ':status': 200
  });
  
  // Add to active streams
  streams.add(stream);
  
  // Handle client disconnect
  stream.on('close', () => {
    streams.delete(stream);
  });
  
  // Send initial data
  stream.write('event: connect\ndata: Connected\n\n');
});

server.listen(8443, () => {
  console.log('HTTP/2 Server running on https://localhost:8443');
});


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!