誤解
WebSocketとSocket.IOに関する一般的な誤解はほとんどありません。
最初の誤解は、Socket.IOを使用する方がWebSocketを使用するよりもはるかに簡単であるということです。以下の例を参照してください。
2つ目の誤解は、WebSocketがブラウザーで広くサポートされていないことです。詳細については、以下を参照してください。
3つ目の誤解は、Socket.IOが古いブラウザーのフォールバックとして接続をダウングレードすることです。実際には、ブラウザーが古いものであると想定し、サーバーへのAJAX接続を開始します。これは、トラフィックが交換された後で、WebSocketをサポートするブラウザーでアップグレードされます。詳細については、以下を参照してください。
私の実験
WebSocketとSocket.IOの違いを示すために、npmモジュールを作成しました。
これはサーバー側とクライアント側のコードの簡単な例です。クライアントはWebSocketまたはSocket.IOを使用してサーバーに接続し、サーバーは1秒間隔で3つのメッセージを送信します。これらのメッセージはクライアントによってDOMに追加されます。
サーバ側
WebSocketとSocket.IOを使用してExpress.jsアプリで同じことを行うサーバー側の例を比較します。
WebSocketサーバー
Express.jsを使用したWebSocketサーバーの例:
var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
console.error('websocket connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');
ソース:https : //github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js
Socket.IOサーバー
Express.jsを使用したSocket.IOサーバーの例:
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
console.error('socket.io connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');
ソース:https : //github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js
クライアント側
ブラウザでWebSocketとSocket.IOを使用して同じことを行うクライアント側の例を比較します。
WebSocketクライアント
バニラJavaScriptを使用したWebSocketクライアントの例:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m) { log("error"); });
s.addEventListener('open', function (m) { log("websocket connection open"); });
s.addEventListener('message', function (m) { log(m.data); });
ソース:https : //github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html
Socket.IOクライアント
バニラJavaScriptを使用したSocket.IOクライアントの例:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });
ソース:https : //github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html
ネットワークトラフィック
ネットワークトラフィックの違いを確認するには、テストを実行します。これが私が得た結果です:
WebSocketの結果
2リクエスト、1.50 KB、0.05秒
これらの2つのリクエストから:
- HTMLページ自体
- WebSocketへの接続アップグレード
(接続アップグレード要求は、101 Switching Protocols応答で開発者ツールに表示されます。)
Socket.IOの結果
6リクエスト、181.56 KB、0.25秒
これらの6つのリクエストから:
- HTMLページ自体
- Socket.IOのJavaScript(180キロバイト)
- 最初のロングポーリングAJAXリクエスト
- 2番目の長いポーリングAJAX要求
- 3番目の長いポーリングAJAX要求
- WebSocketへの接続アップグレード
スクリーンショット
ローカルホストで取得したWebSocketの結果:
localhostで取得したSocket.IOの結果:
自分を試す
クイックスタート:
# Install:
npm i -g websocket-vs-socket.io
# Run the server:
websocket-vs-socket.io
オープンのhttp:// localhostを:3001 /ブラウザで、Shiftキー+ Ctrlキー+ Iとのオープン開発ツール、[ネットワーク]タブを開き、WebSocketのバージョンのネットワークトラフィックを参照してくださいするには、Ctrl + Rとページをリロードしてください。
オープンのhttp:// localhostを:3002 /ブラウザで、Shiftキー+ Ctrlキー+ Iとのオープン開発ツール、[ネットワーク]タブを開き、Socket.IOバージョンのネットワークトラフィックを確認するには、Ctrl + Rとページをリロードしてください。
アンインストールするには:
# Uninstall:
npm rm -g websocket-vs-socket.io
ブラウザの互換性
2016年6月の時点で、WebSocketは、9以上のIEを含め、Opera Miniを除くすべてで機能します。
これは、2016年6月時点で使用できる WebSocketのブラウザ互換性です。
最新情報については、http://caniuse.com/websocketsを参照してください。