このレッスンで学ぶこと
HTTPプロトコルの進化とWebSocket技術の関係を深く理解し、実践的な実装戦略を習得します。
- HTTP/1.1ベースWebSocketの詳細な実装パターン
- HTTP/2 Server Push vs WebSocketの技術的比較と選択基準
- HTTP/3(QUIC)での新しいWebSocket実装アプローチ
- WebTransportによる次世代双方向通信の展望
- 2025年の推奨戦略と実装ガイドライン
HTTPプロトコルの進化とWebSocket技術の関係を深く理解し、実践的な実装戦略を習得します。
HTTP/1.1は現在のWebSocket実装の基盤となる最も重要なプロトコルです。
クライアント側リクエスト
GET /chat HTTP/1.1
Host: example.com:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Origin: https://example.com
User-Agent: Mozilla/5.0 (compatible WebSocket client)
サーバー側レスポンス
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Extensions: permessage-deflate
// サーバー側:Node.js + ws ライブラリでの実装
const WebSocket = require('ws');
const http = require('http');
class HTTP11WebSocketServer {
constructor() {
this.server = http.createServer();
this.wss = new WebSocket.Server({
server: this.server,
handleProtocols: this.handleProtocols.bind(this),
verifyClient: this.verifyClient.bind(this)
});
this.setupHTTP11Handling();
}
setupHTTP11Handling() {
// HTTP/1.1特有の処理
this.server.on('upgrade', (request, socket, head) => {
console.log('HTTP/1.1 Upgrade request received');
console.log('Headers:', request.headers);
// WebSocketハンドシェイクの詳細ログ
this.logUpgradeDetails(request);
// WebSocketサーバーにアップグレード処理を委任
this.wss.handleUpgrade(request, socket, head, (ws) => {
this.wss.emit('connection', ws, request);
});
});
}
handleProtocols(protocols, request) {
console.log('Requested protocols:', protocols);
// プロトコル選択ロジック
const supportedProtocols = ['chat', 'echo', 'binary'];
for (const protocol of protocols) {
if (supportedProtocols.includes(protocol)) {
return protocol;
}
}
return false; // プロトコル拒否
}
verifyClient(info) {
// HTTP/1.1ベースの検証
const { origin, secure, req } = info;
console.log('Client verification:', {
origin,
secure,
userAgent: req.headers['user-agent'],
httpVersion: req.httpVersion
});
// HTTP/1.1の詳細検証
if (req.httpVersion !== '1.1') {
console.log('Rejected: Not HTTP/1.1');
return false;
}
return true;
}
logUpgradeDetails(request) {
console.log('=== HTTP/1.1 WebSocket Upgrade Details ===');
console.log('HTTP Version:', request.httpVersion);
console.log('Method:', request.method);
console.log('URL:', request.url);
console.log('Upgrade header:', request.headers.upgrade);
console.log('Connection header:', request.headers.connection);
console.log('WebSocket Key:', request.headers['sec-websocket-key']);
console.log('WebSocket Version:', request.headers['sec-websocket-version']);
}
}
// クライアント側:堅牢なWebSocket実装
class ProductionWebSocket {
constructor(url, options = {}) {
this.url = url;
this.options = {
protocols: options.protocols || [],
reconnectInterval: options.reconnectInterval || 3000,
maxReconnectAttempts: options.maxReconnectAttempts || 10,
heartbeatInterval: options.heartbeatInterval || 30000,
...options
};
this.reconnectAttempts = 0;
this.isConnected = false;
this.messageQueue = [];
this.connect();
}
connect() {
try {
// HTTP/1.1ベースWebSocket接続
this.ws = new WebSocket(this.url, this.options.protocols);
// HTTP/1.1固有のイベント処理
this.ws.onopen = this.handleOpen.bind(this);
this.ws.onmessage = this.handleMessage.bind(this);
this.ws.onclose = this.handleClose.bind(this);
this.ws.onerror = this.handleError.bind(this);
} catch (error) {
console.error('WebSocket connection failed:', error);
this.scheduleReconnect();
}
}
handleOpen(event) {
console.log('HTTP/1.1 WebSocket connected');
this.isConnected = true;
this.reconnectAttempts = 0;
// HTTP/1.1接続の詳細ログ
console.log('Protocol selected:', this.ws.protocol);
console.log('Extensions:', this.ws.extensions);
// キューに蓄積されたメッセージを送信
this.flushMessageQueue();
// ハートビート開始
this.startHeartbeat();
}
handleMessage(event) {
try {
const data = JSON.parse(event.data);
// ハートビート応答の処理
if (data.type === 'pong') {
this.lastPongTime = Date.now();
return;
}
// アプリケーションメッセージの処理
this.onMessage?.(data);
} catch (error) {
console.error('Message parsing error:', error);
}
}
handleClose(event) {
console.log('WebSocket connection closed:', event.code, event.reason);
this.isConnected = false;
this.stopHeartbeat();
// HTTP/1.1特有のクローズコード処理
this.handleCloseCode(event.code);
// 自動再接続
if (this.shouldReconnect(event.code)) {
this.scheduleReconnect();
}
}
handleCloseCode(code) {
const closeCodes = {
1000: 'Normal Closure',
1001: 'Going Away',
1002: 'Protocol Error',
1003: 'Unsupported Data',
1005: 'No Status Received',
1006: 'Abnormal Closure',
1007: 'Invalid frame payload data',
1008: 'Policy Violation',
1009: 'Message Too Big',
1010: 'Mandatory Extension',
1011: 'Internal Server Error',
1015: 'TLS Handshake'
};
console.log(`Close code ${code}: ${closeCodes[code] || 'Unknown'}`);
}
startHeartbeat() {
this.heartbeatTimer = setInterval(() => {
if (this.isConnected) {
this.send({ type: 'ping', timestamp: Date.now() });
}
}, this.options.heartbeatInterval);
}
send(data) {
const message = JSON.stringify(data);
if (this.isConnected && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(message);
} else {
// 接続していない場合はキューに追加
this.messageQueue.push(message);
}
}
}
// サブプロトコル・拡張機能の活用
class AdvancedHTTP11WebSocket {
constructor(url) {
this.url = url;
this.setupAdvancedFeatures();
}
setupAdvancedFeatures() {
// 複数のサブプロトコルとの対応
const protocols = [
'chat-v1', // テキストチャット
'binary-v1', // バイナリデータ
'json-rpc-2.0' // JSON-RPC
];
// 拡張機能の要求
// permessage-deflate: メッセージ圧縮
// x-webkit-deflate-frame: Safari対応
this.ws = new WebSocket(this.url, protocols);
this.ws.onopen = () => {
console.log('Selected protocol:', this.ws.protocol);
console.log('Available extensions:', this.ws.extensions);
// プロトコル別の初期化
this.initializeProtocol(this.ws.protocol);
};
}
initializeProtocol(protocol) {
switch (protocol) {
case 'chat-v1':
this.setupChatProtocol();
break;
case 'binary-v1':
this.setupBinaryProtocol();
break;
case 'json-rpc-2.0':
this.setupJsonRpcProtocol();
break;
}
}
setupChatProtocol() {
// チャットプロトコル固有の処理
this.messageHandlers = {
'chat.message': this.handleChatMessage.bind(this),
'chat.typing': this.handleTypingIndicator.bind(this),
'chat.user_joined': this.handleUserJoined.bind(this)
};
}
setupBinaryProtocol() {
// バイナリデータ処理
this.ws.binaryType = 'arraybuffer';
this.binaryHandlers = {
image: this.handleImageData.bind(this),
audio: this.handleAudioData.bind(this),
file: this.handleFileTransfer.bind(this)
};
}
// 圧縮機能の活用
sendCompressedMessage(data) {
// permessage-deflate拡張が利用可能かチェック
if (this.ws.extensions.includes('permessage-deflate')) {
// 大きなデータの場合、自動的に圧縮される
this.ws.send(JSON.stringify(data));
} else {
// 手動圧縮の実装
this.sendManuallyCompressed(data);
}
}
}
HTTP/2は双方向通信機能を提供しますが、WebSocketとは根本的に異なるアプローチです。
// HTTP/2 Server Push(現在は非推奨)
// 注意:多くのブラウザで廃止されています
class HTTP2ServerPush {
constructor() {
// HTTP/2 Server Pushの仕組み
this.limitations = {
direction: '一方向(サーバー → クライアント)',
model: 'リクエスト/レスポンス',
state: 'ステートレス',
timing: 'リクエスト予測ベース'
};
}
// HTTP/2 Server Pushの実装例
setupServerPush(response) {
// この機能は多くのブラウザで廃止済み
if (response.stream.pushAllowed) {
response.stream.pushStream({
':path': '/api/updates',
':method': 'GET'
}, (err, pushStream) => {
if (err) {
console.error('Server Push failed:', err);
return;
}
pushStream.respond({
':status': 200,
'content-type': 'application/json'
});
pushStream.end(JSON.stringify({
type: 'update',
data: 'Server pushed data'
}));
});
}
}
}
// HTTP/2上でのWebSocket実装
class WebSocketOverHTTP2 {
constructor(url) {
this.url = url;
this.http2Features = {
multiplexing: true, // 多重化対応
headerCompression: true, // HPACKヘッダー圧縮
serverPush: false, // Server Push非使用
binaryFraming: true // バイナリフレーミング
};
this.connectWithHTTP2Support();
}
connectWithHTTP2Support() {
// HTTP/2対応WebSocket接続
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log('WebSocket over HTTP/2 connected');
// HTTP/2接続の確認
this.detectHTTP2Features();
};
}
detectHTTP2Features() {
// ブラウザのHTTP/2サポート検証
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(registration => {
// Service Worker経由でHTTP/2機能を確認
this.checkHTTP2Protocol(registration);
});
}
}
// HTTP/2の多重化機能を活用した複数WebSocket管理
createMultiplexedConnections() {
const connections = {};
// 同一ドメインで複数のWebSocket接続
// HTTP/2では同一TCP接続を再利用
['chat', 'notifications', 'updates'].forEach(channel => {
connections[channel] = new WebSocket(
`wss://example.com/${channel}`,
[`${channel}-protocol`]
);
connections[channel].onopen = () => {
console.log(`${channel} channel established over HTTP/2`);
};
});
return connections;
}
}
特徴 | HTTP/2 Server Push | WebSocket over HTTP/2 |
---|---|---|
通信方向 | 一方向のみ | 完全な双方向 |
接続モデル | リクエスト/レスポンス | 持続的接続 |
ブラウザサポート | 廃止済み(Chrome 106+) | 全ブラウザ対応 |
リアルタイム性 | 予測ベース | 真のリアルタイム |
オーバーヘッド | HTTPヘッダー毎回 | 最小限のフレーム |
2025年の推奨 | 使用非推奨 | 強く推奨 |
// HTTP/2の多重化機能を活用
class OptimizedWebSocketHTTP2 {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.channels = new Map();
this.setupMultiplexing();
}
setupMultiplexing() {
// HTTP/2では同一ドメインへの複数接続が効率的
const channelConfigs = [
{ name: 'realtime', path: '/ws/realtime', priority: 'high' },
{ name: 'notifications', path: '/ws/notifications', priority: 'medium' },
{ name: 'sync', path: '/ws/sync', priority: 'low' },
{ name: 'telemetry', path: '/ws/telemetry', priority: 'low' }
];
channelConfigs.forEach(config => {
this.createChannel(config);
});
}
createChannel(config) {
const ws = new WebSocket(
`${this.baseUrl}${config.path}`,
[`${config.name}-v1`]
);
ws.onopen = () => {
console.log(`${config.name} channel ready (HTTP/2 multiplexed)`);
// HTTP/2の優先度制御を活用
this.configurePriority(ws, config.priority);
};
ws.onmessage = (event) => {
this.routeMessage(config.name, event);
};
this.channels.set(config.name, {
socket: ws,
config: config,
messageQueue: [],
stats: { sent: 0, received: 0 }
});
}
configurePriority(ws, priority) {
// HTTP/2ストリーム優先度の影響を考慮
// 実際の優先度制御はブラウザとサーバーが処理
const metadata = {
priority: priority,
timestamp: Date.now(),
http2Multiplexed: true
};
ws.send(JSON.stringify({
type: 'channel.config',
metadata: metadata
}));
}
// HTTP/2のヘッダー圧縮効果を最大化
sendOptimizedMessage(channel, data) {
const channelInfo = this.channels.get(channel);
if (!channelInfo) return;
// 共通ヘッダーの最適化(HPACK圧縮効果)
const message = {
v: '1.0', // バージョン
ts: Date.now(), // タイムスタンプ
id: this.generateMessageId(), // メッセージID
ch: channel, // チャネル名
data: data // ペイロード
};
channelInfo.socket.send(JSON.stringify(message));
channelInfo.stats.sent++;
}
// HTTP/2接続の統計情報
getConnectionStats() {
const stats = {
totalChannels: this.channels.size,
http2Features: {
multiplexing: true,
headerCompression: true,
serverPush: false // WebSocketには不要
},
channelStats: {}
};
this.channels.forEach((info, name) => {
stats.channelStats[name] = {
readyState: info.socket.readyState,
messagesSent: info.stats.sent,
messagesReceived: info.stats.received,
priority: info.config.priority
};
});
return stats;
}
}
HTTP/3はQUICプロトコル上で動作し、WebSocketに革新的な改良をもたらします。
// HTTP/3 (QUIC)上のWebSocket実装
class WebSocketOverQUIC {
constructor(url, options = {}) {
this.url = url;
this.quicFeatures = {
connectionMigration: true, // 接続移行
zeroRTTReconnection: true, // 0-RTT再接続
builtInTLS: true, // TLS統合
multiplexing: true, // ストリーム多重化
connectionLessHandshake: true // コネクションレス
};
this.options = {
enableQUIC: true,
enable0RTT: options.enable0RTT !== false,
enableConnectionMigration: options.enableConnectionMigration !== false,
...options
};
this.connectWithQUIC();
}
async connectWithQUIC() {
try {
// HTTP/3対応の確認
if (!this.isHTTP3Supported()) {
console.log('HTTP/3 not supported, falling back to HTTP/2');
return this.fallbackToHTTP2();
}
// QUIC接続の確立
this.ws = new WebSocket(this.url, {
protocols: ['websocket-over-quic-v1'],
// HTTP/3固有のオプション(将来の実装)
preferredVersion: 'h3',
enableQUICFeatures: this.options.enableQUIC
});
this.setupQUICEventHandlers();
} catch (error) {
console.error('QUIC WebSocket connection failed:', error);
this.fallbackToHTTP2();
}
}
setupQUICEventHandlers() {
this.ws.onopen = (event) => {
console.log('WebSocket over QUIC connected');
console.log('QUIC features active:', this.detectQUICFeatures());
// 0-RTTデータの送信(再接続時)
if (this.has0RTTData()) {
this.send0RTTData();
}
};
// QUIC固有のイベント(将来の実装)
this.ws.onconnectionmigration = (event) => {
console.log('QUIC connection migrated:', event.newPath);
this.handleConnectionMigration(event);
};
this.ws.onnetworkchange = (event) => {
console.log('Network changed, QUIC adapting:', event);
// QUICの自動ネットワーク適応
};
}
detectQUICFeatures() {
// 現在利用可能なQUIC機能の検出
return {
version: this.ws.protocol || 'unknown',
connectionMigration: this.ws.connectionMigrationEnabled || false,
zeroRTT: this.ws.zeroRTTEnabled || false,
congestionControl: this.ws.congestionControl || 'cubic'
};
}
// 0-RTT再接続の実装
enable0RTTReconnection() {
// 前回のセッション情報を保存
this.sessionTicket = {
ticket: this.ws.sessionTicket,
timestamp: Date.now(),
serverParams: this.ws.serverTransportParams
};
localStorage.setItem('quic-session', JSON.stringify(this.sessionTicket));
}
send0RTTData() {
const cachedData = this.get0RTTCachedData();
if (cachedData && this.ws.readyState === WebSocket.CONNECTING) {
// 0-RTTでの即座のデータ送信
this.ws.send(JSON.stringify({
type: '0rtt-data',
cached: true,
data: cachedData
}));
}
}
// 接続移行の処理
handleConnectionMigration(event) {
console.log('Migrating connection from', event.oldPath, 'to', event.newPath);
// アプリケーション状態の保持
this.preserveApplicationState();
// 新しいパスでの接続確認
this.validateNewConnection();
}
isHTTP3Supported() {
// HTTP/3サポートの検出
if (typeof window === 'undefined') return false;
// 現在の検出方法(2025年時点)
return 'serviceWorker' in navigator &&
'fetch' in window &&
window.chrome &&
window.chrome.loadTimes; // Chrome/Edge固有
}
}
// QUIC固有の機能を活用したWebSocket管理
class QUICOptimizedWebSocket {
constructor(url) {
this.url = url;
this.quicStats = {
connectionMigrations: 0,
zeroRTTAttempts: 0,
zeroRTTSuccesses: 0,
packetLoss: 0,
rttMeasurements: []
};
this.setupQUICOptimizations();
}
setupQUICOptimizations() {
// QUIC多重化ストリーム活用
this.streams = {
highPriority: this.createPriorityStream('high'),
normalPriority: this.createPriorityStream('normal'),
lowPriority: this.createPriorityStream('low'),
background: this.createPriorityStream('background')
};
}
createPriorityStream(priority) {
const ws = new WebSocket(this.url, [`stream-${priority}-v1`]);
ws.onopen = () => {
console.log(`${priority} priority stream established`);
// QUIC固有の設定
this.configureQUICStream(ws, priority);
};
return ws;
}
configureQUICStream(ws, priority) {
// QUICストリーム優先度設定(将来の実装)
const priorityConfig = {
urgency: this.getPriorityUrgency(priority),
incremental: priority !== 'high',
weight: this.getPriorityWeight(priority)
};
ws.send(JSON.stringify({
type: 'stream.config',
priority: priorityConfig
}));
}
// ネットワーク変更への適応
handleNetworkChange() {
// QUICの接続移行機能を活用
console.log('Network change detected, QUIC will handle migration');
// アプリケーションレベルでの準備
this.prepareForMigration();
}
prepareForMigration() {
// 未送信メッセージのバックアップ
this.backupPendingMessages();
// セッション状態の保存
this.saveSessionState();
// 移行完了後の復元準備
this.prepareMigrationRecovery();
}
// パフォーマンス測定
measureQUICPerformance() {
return {
rtt: this.measureRTT(),
throughput: this.measureThroughput(),
packetLoss: this.quicStats.packetLoss,
connectionMigrations: this.quicStats.connectionMigrations,
zeroRTTSuccessRate: this.quicStats.zeroRTTSuccesses / this.quicStats.zeroRTTAttempts
};
}
}
WebTransportは、HTTP/3上での新しい双方向通信APIで、WebSocketの代替となる可能性があります。
// WebTransport実装(実験的機能)
class WebTransportConnection {
constructor(url) {
this.url = url;
this.transport = null;
this.streams = new Map();
this.datagrams = [];
this.connectWebTransport();
}
async connectWebTransport() {
try {
// WebTransportサポートの確認
if (!('WebTransport' in window)) {
throw new Error('WebTransport not supported');
}
// WebTransport接続の確立
this.transport = new WebTransport(this.url);
await this.transport.ready;
console.log('WebTransport connection established');
this.setupWebTransportHandlers();
} catch (error) {
console.error('WebTransport connection failed:', error);
console.log('Falling back to WebSocket');
this.fallbackToWebSocket();
}
}
setupWebTransportHandlers() {
// ストリーム処理
this.handleIncomingStreams();
// データグラム処理
this.handleIncomingDatagrams();
// 接続状態監視
this.transport.closed.then(() => {
console.log('WebTransport connection closed');
}).catch(error => {
console.error('WebTransport connection error:', error);
});
}
async handleIncomingStreams() {
const reader = this.transport.incomingBidirectionalStreams.getReader();
while (true) {
try {
const { value: stream, done } = await reader.read();
if (done) break;
console.log('New bidirectional stream received');
this.processIncomingStream(stream);
} catch (error) {
console.error('Stream reading error:', error);
break;
}
}
}
async handleIncomingDatagrams() {
const reader = this.transport.datagrams.readable.getReader();
while (true) {
try {
const { value: datagram, done } = await reader.read();
if (done) break;
console.log('Datagram received:', datagram);
this.processDatagram(datagram);
} catch (error) {
console.error('Datagram reading error:', error);
break;
}
}
}
// ストリームベース通信(信頼性あり)
async sendStreamMessage(data) {
try {
const stream = await this.transport.createBidirectionalStream();
const writer = stream.writable.getWriter();
const encoder = new TextEncoder();
const encoded = encoder.encode(JSON.stringify(data));
await writer.write(encoded);
await writer.close();
console.log('Stream message sent');
} catch (error) {
console.error('Stream sending error:', error);
}
}
// データグラムベース通信(低遅延)
async sendDatagramMessage(data) {
try {
const writer = this.transport.datagrams.writable.getWriter();
const encoder = new TextEncoder();
const encoded = encoder.encode(JSON.stringify(data));
await writer.write(encoded);
console.log('Datagram sent');
} catch (error) {
console.error('Datagram sending error:', error);
}
}
// WebSocketフォールバック
fallbackToWebSocket() {
console.log('Initializing WebSocket fallback');
this.websocket = new WebSocket(this.url.replace('https://', 'wss://'));
this.websocket.onopen = () => {
console.log('WebSocket fallback connected');
};
this.websocket.onmessage = (event) => {
this.processWebSocketMessage(event.data);
};
}
}
特徴 | WebSocket | WebTransport |
---|---|---|
基盤プロトコル | TCP上のHTTP/1.1 | QUIC上のHTTP/3 |
データ配信 | 順序保証あり | ストリーム/データグラム選択可 |
接続確立 | TCP 3-way handshake | 0-RTT可能 |
多重化 | 単一ストリーム | 複数ストリーム並列 |
ブラウザサポート | 全ブラウザ | Chrome/Edge(実験的) |
2025年推奨 | プロダクション使用 | 実験・評価段階 |
// 2025年推奨:プログレッシブWebSocket実装
class ProgressiveWebSocketStrategy {
constructor(url, options = {}) {
this.url = url;
this.options = options;
// プロトコルサポートの優先順位
this.protocolPriority = [
'websocket-over-http3', // 実験的:HTTP/3対応ブラウザ
'websocket-over-http2', // 推奨:HTTP/2環境
'websocket-over-http1.1' // 基盤:全ブラウザ対応
];
this.implementProgressiveConnection();
}
async implementProgressiveConnection() {
// 機能検出とプロトコル選択
const supportedProtocol = await this.detectBestProtocol();
switch (supportedProtocol) {
case 'http3':
await this.connectWithHTTP3();
break;
case 'http2':
await this.connectWithHTTP2();
break;
default:
await this.connectWithHTTP11();
}
}
async detectBestProtocol() {
// HTTP/3サポート検出
if (await this.isHTTP3Available()) {
console.log('Using HTTP/3 for WebSocket');
return 'http3';
}
// HTTP/2サポート検出
if (await this.isHTTP2Available()) {
console.log('Using HTTP/2 for WebSocket');
return 'http2';
}
console.log('Using HTTP/1.1 for WebSocket');
return 'http1.1';
}
async connectWithHTTP11() {
// HTTP/1.1基盤実装(最も安定)
this.ws = new WebSocket(this.url, this.options.protocols);
this.ws.onopen = () => {
console.log('HTTP/1.1 WebSocket established');
this.recordProtocolUsage('http1.1');
};
return this.setupStandardWebSocket();
}
async connectWithHTTP2() {
// HTTP/2最適化実装
this.ws = new WebSocket(this.url, this.options.protocols);
// HTTP/2の多重化を活用した追加接続
this.additionalChannels = this.setupMultiplexedChannels();
this.ws.onopen = () => {
console.log('HTTP/2 WebSocket with multiplexing');
this.recordProtocolUsage('http2');
};
return this.setupOptimizedWebSocket();
}
async connectWithHTTP3() {
// HTTP/3実験的実装
try {
// WebTransportの試行
if ('WebTransport' in window) {
this.transport = new WebTransport(this.url);
await this.transport.ready;
console.log('WebTransport over HTTP/3 established');
this.recordProtocolUsage('webtransport');
return this.setupWebTransport();
}
// 従来WebSocket over HTTP/3
this.ws = new WebSocket(this.url, this.options.protocols);
this.recordProtocolUsage('websocket-http3');
return this.setupQUICWebSocket();
} catch (error) {
console.log('HTTP/3 failed, falling back to HTTP/2');
return this.connectWithHTTP2();
}
}
// パフォーマンス監視と自動最適化
startPerformanceMonitoring() {
this.performanceMonitor = {
latency: [],
throughput: [],
reliability: { connected: 0, disconnected: 0 }
};
setInterval(() => {
this.measurePerformance();
this.optimizeConnection();
}, 30000);
}
measurePerformance() {
const metrics = {
timestamp: Date.now(),
rtt: this.measureRoundTripTime(),
throughput: this.calculateThroughput(),
protocol: this.currentProtocol
};
this.performanceMonitor.latency.push(metrics.rtt);
this.performanceMonitor.throughput.push(metrics.throughput);
return metrics;
}
// プロトコル利用統計の収集
recordProtocolUsage(protocol) {
this.currentProtocol = protocol;
const usage = JSON.parse(localStorage.getItem('websocket-protocol-usage') || '{}');
usage[protocol] = (usage[protocol] || 0) + 1;
usage.lastUsed = protocol;
usage.timestamp = Date.now();
localStorage.setItem('websocket-protocol-usage', JSON.stringify(usage));
}
}
// エンタープライズグレードWebSocket実装
class EnterpriseWebSocketManager {
constructor(config) {
this.config = {
primaryUrl: config.primaryUrl,
fallbackUrls: config.fallbackUrls || [],
healthCheckInterval: config.healthCheckInterval || 30000,
maxReconnectAttempts: config.maxReconnectAttempts || 10,
loadBalancing: config.loadBalancing || 'round-robin',
monitoring: config.monitoring || {},
...config
};
this.connectionPool = new Map();
this.healthStatus = new Map();
this.loadBalancer = new LoadBalancer(this.config.loadBalancing);
this.initializeEnterpriseFeatures();
}
initializeEnterpriseFeatures() {
// 複数サーバーへの接続プール
this.setupConnectionPool();
// ヘルスチェックシステム
this.startHealthMonitoring();
// ロードバランシング
this.configureLoadBalancing();
// 監視・ログシステム
this.setupMonitoring();
}
setupConnectionPool() {
const urls = [this.config.primaryUrl, ...this.config.fallbackUrls];
urls.forEach((url, index) => {
const connection = new ProductionWebSocket(url, {
id: `connection-${index}`,
isPrimary: index === 0,
protocols: this.config.protocols,
autoReconnect: true
});
this.connectionPool.set(url, connection);
this.healthStatus.set(url, { status: 'connecting', lastCheck: Date.now() });
});
}
startHealthMonitoring() {
this.healthCheckTimer = setInterval(() => {
this.performHealthChecks();
}, this.config.healthCheckInterval);
}
async performHealthChecks() {
const healthPromises = Array.from(this.connectionPool.entries()).map(
([url, connection]) => this.checkConnectionHealth(url, connection)
);
const results = await Promise.allSettled(healthPromises);
results.forEach((result, index) => {
const url = Array.from(this.connectionPool.keys())[index];
if (result.status === 'fulfilled') {
this.healthStatus.set(url, result.value);
} else {
this.healthStatus.set(url, {
status: 'unhealthy',
error: result.reason,
lastCheck: Date.now()
});
}
});
// ヘルスステータスに基づく自動フェイルオーバー
this.handleHealthResults();
}
// エンタープライズ監視機能
setupMonitoring() {
this.metrics = {
totalConnections: 0,
activeConnections: 0,
messagesSent: 0,
messagesReceived: 0,
errors: 0,
latencyHistory: [],
uptimeStart: Date.now()
};
// 監視データの定期送信
if (this.config.monitoring.endpoint) {
setInterval(() => {
this.sendMonitoringData();
}, this.config.monitoring.interval || 60000);
}
}
// セキュリティ強化
setupSecurityFeatures() {
return {
authentication: this.setupAuthentication(),
authorization: this.setupAuthorization(),
rateLimiting: this.setupRateLimiting(),
inputValidation: this.setupInputValidation(),
auditLogging: this.setupAuditLogging()
};
}
// 使用統計とレポート
generateUsageReport() {
const report = {
timestamp: new Date().toISOString(),
protocol: {
http11: this.getProtocolUsage('http1.1'),
http2: this.getProtocolUsage('http2'),
http3: this.getProtocolUsage('http3')
},
performance: {
averageLatency: this.calculateAverageLatency(),
throughput: this.calculateThroughput(),
reliability: this.calculateReliability()
},
errors: this.getErrorSummary(),
recommendations: this.generateRecommendations()
};
return report;
}
}
基盤技術
パフォーマンス最適化
信頼性・運用
将来対応
現在(2025年)
短期(2025-2026年)
中長期(2026年以降)
現在の開発における価値
将来への準備価値
このレッスンの内容を理解できましたら、完了マークをつけて次のレッスンに進みましょう。