[JavaScript] Socket.IO を用いたチャットアプリのご紹介

前回は、JavaのThreadを用いての、同期・非同期処理のサンプルコードを御紹介しました。
今回は、Socket.IO を用いたチャットアプリについて、簡単にご紹介したいと思います。

■チャットアプリとは
 チャットアプリというのは、不特定多数の端末から、文字等の情報を送信しあい、会話をするためのアプリです。
 LINEやSkypeのようなアプリが一般的かと思います。

■通常のWebサービスと、チャット違うところ
 通常のWebページを表示するようなプログラムでは、不特定多数の端末から、URL情報を受け取って、
 何らかの文字列(HTML等)を返却します。

 基本的に、サーバ側ではクライアント側と接続し続けることはなく、
 HTMLページを表示し終わったら、そこで終了です。

 しかし、チャットアプリでは、たとえばAさんとBさんが会話をしているなら、
 AさんとBさんの書き込みを、お互いに確認しあえないといけないです。
 ※リアルタイム性が無いといけないです

■チャットを実現する方法
 チャットの仕組みを作るにあたって、いくつかの手段があります。

 ・通常のWebサービスと同じHTTPプロトコルを利用して、ページを表示する
  何秒かおきに再通信を行って画面を刷新するという方法があります
  通信を頻繁に行わなければならないという欠点はありますが、
  大体どのような環境でも動作する利点があります。

 ・Comet という仕組みを利用する
  サーバの方で、HTTPコネクションを維持し続けて、
  Aさんが書きこんだタイミングで、サーバ側からBさんに通知して、Bさんの画面を刷新します。
  HTTPコネクションを維持し続けることで、通信の回数は減りますが、
  サーバ側で相当数のHTTPコネクションを維持し続けないといけないです。

 ・WebSocketというプロトコルを利用する
  上述の2つの仕組みと比べて、双方向通信用のプロトコルを利用するので
  軽く動作することが特徴ですが、サーバやブラウザが、このプロトコルに対応している必要があります。

■Socket.IOについて
 チャットを実現する方法にはいくつかの種類がありますが、
 サーバやクライアントの環境によって、実現できる手段が変わってきます。
 それを、環境に応じて自動的に、どの通信方法を取るのか決めてくれるのが、Socket.IOです。

 通信部分が Socket.IO 内に隠蔽されていますので、利用者は容易に
 チャットアプリのような、リアルタイム通信を実現できます。

■node.jsについて
 node.js は、サーバ側で動作するJavaScriptです。
 上述の Socket.IO のライブラリを簡単に扱うことが出来ます。
 今回は、この node.js を利用して、チャットアプリを実現しようと思います。

■node.js のインストール
 <前提条件>
  ・Windows環境へのインストール手順になります
  ・git コマンドが利用できなければなりません。
   git のインストール方法については、ここでは割愛します。
  ・git の clone には ToritoiseGit を利用します。
   ToritoiseGit のインストール方法についても割愛します。

 1)node.jsをインストールしたいディレクトリで、
   ToritoiseGit – Clone を選択します



 2)URLに「git://github.com/marcelklehr/nodist.git」と入力し、
   Putty認証キーのチェックを外して、OKボタンを押下します



 3)成功と表示されれば成功です



 4)インストール後、Windowsの環境変数に対して、「<インストールディレクト>\nodist\bin」へパスを通します
   システムのプロパティを表示し、「詳細設定」タブを表示します。
   画面下部にある「環境変数」ボタンを押下します。



 5)画面下部の「システム環境変数」から「Path」という変数を探します
   選択状態にして、「編集」ボタンを押下します



 6)一番右側にフォーカスを移動後、「;<インストールディレクト>\nodist\bin」と入力します。
   ※先頭に「;」をつけるのを忘れないようにしてください



 7)今度は、「システム環境変数」に、「NODIST_PREFIX」という変数を追加します。
   「システム環境変数」の下部にある、「新規」を選択します。



 8)「変数名」に「NODIST_PREFIX」を、変数値に「<インストールディレクト>\nodist\bin」を入力します。



 9)コマンドプロンプトを起動し、「<インストールディレクト>\nodist\bin」へ移動します。
   その後、「nodist update」を実行します。



■Socket.IOのインストール
 コマンドプロンプトで、「<インストールディレクト>\nodist\bin」へ移動します。
 (先ほどと同じディレクトリです)
 その後、「npm install socket.io」と実行します。



■テスト用のプログラムを作成
 「<インストールディレクト>\nodist\bin」の下に、以下2つのファイルを作成し、保存します。

 ・sample.html

<html>
<head>
<meta charset="UTF-8">
<title>テスト</title>
</head>
<body>
    <input type="text" id="input_data" style="width:200px;" />
    <button onclick="send();">メッセージを送信</button>
    <div id="msg"></div>
</body>
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
    //送受信したメッセージを表示する場所
    var messageList = document.getElementById("msg");

    //node.jsとの接続を確立するための変数を定義
    var socketio = io.connect('http://localhost:1234');

    //接続が確立した後のCB処理登録
    socketio.on("connected", function(name) {});

    //誰かのメッセージが書き込まれた時の処理
    socketio.on("publish", function (data) { 
        var insertMessage = document.createElement('div');
        insertMessage.innerHTML = data.value;
        messageList.appendChild(insertMessage);
    });

    //接続が切れた時の処理
    socketio.on("disconnect", function () {});

    //PCから接続したことをメッセージで設定する
    var randomName = Math.floor(Math.random() * 100) + ":PC";

    //実際に接続を開始する
    socketio.emit("connected", randomName);

    //メッセージを送信する処理
    //PCから送信ボタンを押下した際に実行する
    function send() {
        var input = document.getElementById('input_data');
        socketio.emit("publish", {value: randomName + "::" + input});
        input.value = '';
    }
</script>
</html>

 ・sample.js

//モジュールオブジェクトの初期化
var fs = require("fs");

//サーバ情報を設定する
//通信プロトコルがhttp、ポート番号が「1234」となる
var server = require("http").createServer(function(req, res) {
    //レスポンスヘッダに、text/htmlを設定
    res.writeHead(200, {"Content-Type":"text/html"});

    //ここに作成したサンプルのhtmlファイルを設定する
    var output = fs.readFileSync("./sample.html", "utf-8");

    res.end(output);
}).listen(1234);

//上記サーバ設定で、socket.ioで応答待ち状態になる
var io = require("socket.io").listen(server);

//ユーザ管理ハッシュ
var userHash = {};

//イベントを定義する
io.sockets.on("connection", function (socket) {
    //誰かが入室した際に、他のユーザに対してメッセージを送信する
    socket.on("connected", function (name) {
        var msg = name + "::入室";
        userHash[socket.id] = name;
        io.sockets.emit("publish", {value: msg});
    });

    //誰かがメッセージを送信した際に、他のユーザに対してメッセージを送信する
    socket.on("publish", function (data) {
        io.sockets.emit("publish", {value:data.value});
    });

    //誰かが退室した際に、他のユーザに対してメッセージを送信する
    socket.on("disconnect", function () {
        if (userHash[socket.id]) {
            var msg = userHash[socket.id] + "::退室";
            delete userHash[socket.id];
            io.sockets.emit("publish", {value: msg});
        }
    });
});

■テスト用のプログラムを実行する
 コマンドプロンプトを起動して、「<インストールディレクト>\nodist\bin」に移動します。
 その後、「node sample.js」を実行します。



 正常に実行された場合、コマンドプロンプトは応答を返さずに待ち状態に入ります。

■テスト用プログラムにブラウザから接続する
 PC上から、任意のブラウザ(IE等)を起動して、
 「http://localhost:1234/に接続します。

 今回は、InternetExplorerと、GoogleChromeでアクセスしてみました。



 お互いのブラウザで、それぞれメッセージをやりとりすることが出来ます。



■まとめ
 以上で、node.js + Socket.IO を用いた、簡単なチャットについてのご紹介を終わります。
 Socket.IOの技術自体は、JavaScriptだけではなく、AndroidやiOSでもライブラリを組み込むことで
 利用することが出来ますので、今回はチャットアプリのご紹介になりましたが、
 「双方向通信」の方法の1つの手段としても用いることが出来るかなと思います。

 ここまでご覧いただきまして、誠にありがとうございました。


弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*