チャットアプリ開発に見る、Socket.IOの基本ライブラリの使い方:Socket.IOで始めるWebSocket超入門(2)(2/3 ページ)
本連載では、WebSocketを扱えるNode.jsのライブラリ「Socket.IO」の使い方について解説します。今回は、チャットアプリ開発を例に、双方向通信、ブロードキャスト送信、個別送信などを実装する際のSocket.IOの使い方について。
双方向通信の実装(データの送受信)
次に、双方向通信によるデータ送受信の実装についてです。ひな型の処理の流れに沿って説明します。ポイントは、emitは送信、onは受信ということです。
| データの送信 | データの受信 | |
|---|---|---|
| emit(送信イベント名, 送信データ) 関数 | on(受信イベント名, 受信データ) 関数 |
クライアントからサーバへのデータ送信
$("form").submit(function(e){
var message = $("#msgForm").val();
$("#msgForm").val('');
// C03. client_to_serverイベント・データを送信する
socket.emit("client_to_server", {value : message});
e.preventDefault();
});
- C03. client_to_serverイベント・データを送信する
フォームがsubmitされたら入力値を取得し、その値をclient_to_serverイベントとしてサーバへ送信しています。
サーバでのデータ受信とクライアントへのデータ送信
// S04. connectionイベント・データを受信する
io.sockets.on('connection', function(socket) {
// S05. client_to_serverイベント・データを受信する
socket.on('client_to_server', function(data) {
// S06. server_to_clientイベント・データを送信する
io.sockets.emit('server_to_client', {value : data.value});
});
});
- S04. connectionイベント・データを受信する
クライアント〜サーバ間でWebSocket通信が確立すると、io.socketsオブジェクトに対してconnectionイベントが発火(データが送信)されます。このconnectionイベントはWebSocket通信が確立している限り有効です。そのため、connectionイベント受信時のコールバック関数として、必要なサーバサイドの処理を定義することになります。
io.sockets.on('connection', function(socket) {
// この中に必要な処理を記述する
});
- S05. client_to_serverイベント・データを受信する
クライアントから送信されたclient_to_serverイベントとデータを受信しています。
- S06. server_to_clientイベント・データを送信する
受信したデータをserver_to_clientイベントとして、接続している全クライアントへ送信しています。全クライアントにデータを送信するには、「io.sockets.emit(送信イベント名, 送信データ)」を使用します。
io.sockets.emit('server_to_client', {value : data.value});
クライアントでのデータ受信
// C04. server_to_clientイベント・データを受信する
socket.on("server_to_client", function(data){appendMsg(data.value)});
function appendMsg(text) {
$("#chatLogs").append("<div>" + text + "</div>");
}index.html
- C04. server_to_clientイベント・データを受信する
サーバから送信されたserver_to_clientイベントを受信し、データを取得します。コールバック関数(appendMsg(text))で、チャットログエリアにデータを表示します。
以上が、クライアント〜サーバ間での双方向通信の実装です。emit/onを交互に使用してデータをやりとりしていることが確認できたと思います。
その他のデータ送信方法
Socket.IOサーバライブラリには、全クライアントにデータを送信する「io.sockets.emit(送信イベント名, 送信データ)」だけではなく、他にもデータ送信用ライブラリが存在します。
ブロードキャスト送信
まずは、「socket.broadcast.emit(送信イベント名, 送信データ)」です。このライブラリを使用すると、サーバは、データ・イベントを送信したクライアント以外の全てのクライアントにデータを送信します。
では、実際にコードを追加・変更しながら処理の違いを確認してみましょう。ユーザーが入室したら、他のクライアントにだけ入室メッセージ表示する処理を実装します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>websocket-chat</title>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- C01. Socket.IOクライアントライブラリの読み込み -->
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
</head>
<body>
<div class="container">
<h1>WebSocket-Chat</h1>
<form class="form-inline">
<div class="form-group">
<label for="msgForm">名前:</label>
<input type="text" class="form-control" id="msgForm">
</div>
<button type="submit" class="btn btn-primary" id="sendButton">入室</button>
</form>
<div id="chatLogs"></div>
</div>
<script type="text/javascript">
var socket = io.connect(); // C02. ソケットへの接続
var isEnter = false;
var name = '';
// C04. server_to_clientイベント・データを受信する
socket.on("server_to_client", function(data){appendMsg(data.value)});
function appendMsg(text) {
$("#chatLogs").append("<div>" + text + "</div>");
}
$("form").submit(function(e){
var message = $("#msgForm").val();
$("#msgForm").val('');
if (isEnter) {
message = "[" + name + "]: " + message;
// C03. client_to_serverイベント・データを送信する
socket.emit("client_to_server", {value : message});
} else {
name = message;
var entryMessage = name + "さんが入室しました。";
// C05. client_to_server_broadcastイベント・データを送信する
socket.emit("client_to_server_broadcast", {value : entryMessage});
changeLabel();
}
e.preventDefault();
});
function changeLabel() {
$("label").text("メッセージ:");
$("button").text("送信");
isEnter = true;
}
</script>
</body>
</html>
- C05. client_to_server_broadcastイベント・データを送信する
“〜さんが入室しました。”というメッセージをサーバに送信するclient_to_server_broadcastイベントを新しく追加しています。
// S01. 必要なモジュールを読み込む
var http = require('http');
var socketio = require('socket.io');
var fs = require('fs');
// S02. HTTPサーバを生成する
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html', 'utf-8'));
}).listen(3000); // ポート競合の場合は値を変更
// S03. HTTPサーバにソケットをひも付ける(WebSocket有効化)
var io = socketio.listen(server);
// S04. connectionイベント・データを受信する
io.sockets.on('connection', function(socket) {
// S05. client_to_serverイベント・データを受信する
socket.on('client_to_server', function(data) {
// S06. server_to_clientイベント・データを送信する
io.sockets.emit('server_to_client', {value : data.value});
});
// S07. client_to_server_broadcastイベント・データを受信し、送信元以外に送信する
socket.on('client_to_server_broadcast', function(data) {
socket.broadcast.emit('server_to_client', {value : data.value});
});
});
- S07. client_to_server_broadcastイベント・データを受信し、送信元以外に送信する
client_to_server_broadcastイベントより取得した入室メッセージをクライアントに送信する処理を追加しています。
コードの変更・保存が完了したら、アプリケーションの動作を確認します。ターミナルで、websocket-chatディレクトリに移動し、「node app.js」コマンドを実行してください(既に実行中の場合は、1度停止した後に再度実行してください)。その後、ブラウザウィンドウを複数開き、「http://localhost:3000/」にアクセスしてみましょう。
どれか1つのウィンドウで、名前欄に値を入力し、入室ボタンを押下します。
ボタン押下後、入力ウィンドウ以外に、「〜さんが入室しました。」というメッセージが表示されていることが確認できたと思います。
このように、broadcastを利用すると、自分以外の全てのクライアントにメッセージを送信できます。
socket.broadcast.emit('server_to_client', {value : data.value});
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
WebSocketが一番速いアプリケーションサーバはどれだ?
双方向通信を実現するHTML5関連技術WebSocketを実装した3つのアプリケーションサーバの実装の違い・性能などを徹底検証する。
Play2+nginx/Akka/WebSocketで高速双方向通信
Play framework 2.xを既存のWebサーバーと連携させる方法、並列処理や双方向通信を行う方法を紹介します。
Socket.IOでセンサー&MongoDB〜AngularJSアプリ間の通信を行う
家電〜Webアプリ間の双方向通信をSocket.IOで行うアプリについて、サーバー側のArduino連携やMongoDBへのデータ保存などと、クライアント側のAngularJSに分けて動作を解説します。


