リアルタイムウェブを支える技術を学び、実際にWebSocketを用いて簡単なアプリケーションを構築してみる。
Node.jsをインストール(第7回の資料を参照)し、適当な作業用ディレクトリを作成する。
作成したディレクトリ内で以下のコマンドを実行し、Socket.IOをインストールする。
npm install socket.io
その後、以下のJavaScriptを適当な名前で保存し、node (ファイル名.js)
で起動する。
const http = require('http');
const socketIO = require('socket.io');
const app = http.createServer((req, res) => {
res.end(`
<!DOCTYPE html>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.on('message', (message) => {
const p = document.createElement('p');
p.textContent = message;
document.body.appendChild(p);
});
</script>
`);
});
const io = socketIO(app);
io.on('connection', (socket) => {
socket.emit('message', 'Hello, World!');
});
process.stdin.on('data', (data) => {
io.emit('message', data.toString());
});
app.listen(8080, () => {
console.log('Listening localhost:8080...');
});
その後ブラウザでhttp://localhost:8080/を開いて、Hello, World! と表示されればOK。
また、スクリプトを起動したコンソールで適当な文字を入力してEnterを押すと、ブラウザに送られる。
名前の通り、Webにおいてサーバーとブラウザ間でリアルタイム通信を行うための技術のこと。
前回見たように、Ajaxの登場によってWebの能力は飛躍的に向上し、ウェブページを閲覧中にユーザーが好きなタイミングでサーバーに通信を求めることができるようになったが、逆にサーバー側からブラウザ側にデータを送るのは回りくどい処理が必要で、そのままでは大量のデータをリアルタイムに転送することはできなかった。
が、近年は関連技術の進歩と実装が進んでおり、リアルタイム性の高い処理が書きやすくなってきている、という話。
StackOverflowに秀逸な記事と図があるので、これを見ながら解説していく。
What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?
以下にも日本語でちょっとした解説と補足を書いておく。
- 新しい情報がないかサーバーに定期的(5秒おきとか)に情報を取りに行く。
- めっちゃ負荷高いしリアルタイム性低いけど一番簡単。
- Pollingに似ているが、コネクションを維持しておき、新しいデータが来たらレスポンスを返す。
- リアルタイム性が高いが、データを送るたびにコネクションを張り直すのでオーバーヘッドが大きい。
- Long-Pollingと同じくコネクションを維持しておき、新しいデータが来たらストリームでデータを流す。
- オーバーヘッドが少なくリアルタイム性が高い。
- HTTPとは異なるプロトコルで、ソケット通信と同じような全二重通信を行うことができる。
- 同じプロトコルでブラウザとサーバー間で双方向に通信することができ、リアルタイム性も高い。
何故かめちゃくちゃ有名なNode.jsのライブラリ。博多市はNode.jsを知る前にSocket.IOを知った。
ブラウザ-サーバー間でリアルタイム通信を行うための様々な機能を提供してくれるライブラリ。名前の通りWebSocketでの通信を主としているが、WebSocket非対応ブラウザやWebSocketが繋がらない環境のためにSSEやLong-Pollingでのfallbackを用意してくれている。
ブラウザ上でロボットを動かして、リアルタイムで同期するアプリケーションを作ろう。
以下のHTMLとJSを保存して、node robot.js
コマンドを打つとサーバーが起動する。
このままでは単にブラウザ上でロボットが動くだけなので、位置情報をサーバーに送信して接続されているクライアント全員で同期するようなアプリケーションに使用。
Socket.IOのドキュメント: http://socket.io/docs/
- サーバー側で、
socket.on
でコネクションからのメッセージを待ち受けるsocket.emit
で1つのコネクションにメッセージを送信するio.emit
ですべてのコネクションにメッセージを送信する
- クライアント側で、
socket.on
でサーバーからのメッセージを待ち受けるsocket.emit
でサーバーにメッセージを送信する
- nodemonを使用すると開発が楽になる。