次に、双方向通信によるデータ送受信の実装についてです。ひな型の処理の流れに沿って説明します。ポイントは、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();
- });
フォームが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});
- });
- });
クライアント~サーバ間でWebSocket通信が確立すると、io.socketsオブジェクトに対してconnectionイベントが発火(データが送信)されます。このconnectionイベントはWebSocket通信が確立している限り有効です。そのため、connectionイベント受信時のコールバック関数として、必要なサーバサイドの処理を定義することになります。
io.sockets.on('connection', function(socket) { // この中に必要な処理を記述する });
クライアントから送信されたclient_to_serverイベントとデータを受信しています。
受信したデータを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
サーバから送信された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>
“~さんが入室しました。”というメッセージをサーバに送信する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});
- });
- });
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.
HTML5�ス蛛スX 髫ェ蛟�スコ荵斟帷ケ晢スウ郢ァ�ュ郢晢スウ郢ァ�ー