WebSocket+jQueryMobileでリアルタイムにメッセージを表示する

By fukuda - 12/10/16 - このエントリをはてなブックマークに追加このエントリをYahoo!ブックマークに追加このエントリをdel.icio.usに追加このエントリをFC2ブックマークに追加

こんにちは、福田です。
突然ですが、リアルタイム感のあるサイトは見ていて楽しいですよね。
今回はPHPのWebSocketサーバーライブラリ+jQueryMobileを使って、同じサイトを見ている全員にリアルタイムでメッセージを表示するシンプルなアプリケーションを作成してみます。

WebSoketのおさらい

WebSoketは、サーバーとブラウザ間における双方向通信(リアルタイムweb)の通信規格です。
他にもリアルタイムwebを実現するための技術としてAjaxやCometなどがありますが、高負荷などのデメリットも目立ちます。WebSocketはそれらを克服して、いいとこ取りをしたものと言えそうです。ただ、IEでは未実装(2012/10/14現在。バージョン10で実装予定)など、使用する際は環境に注意する必要があります。今回は以下の環境で動作を確認しました。

実装環境

  • さくらVPS CentOS6.3
  • PHP5.3.3
  • FIrefox16
  • Chrome22
  • Sarafi(iOS6)

1.ライブラリをサーバーに配置

以下よりWebSocketサーバーライブラリ「php-websocket」ダウンロードし、サーバー上の任意の場所に解凍します。
https://github.com/lemmingzshadow/php-websocket/downloads
ここでは解凍したディレクトリ名を「lemmingzshadow-php-websocket」とします。

2.アプリケーションのクラスを作成

以下の場所に、Application.phpを継承して新規にクラスを作成します。
lemmingzshadow-php-websocket/server/lib/WebSocket/Application/PopupApplication.php(新規作成)

<?php
namespace WebSocket\Application;
class PopupApplication extends Application
{
    private $_clients = array();

    public function onConnect($client){
        $id = $client->getClientId();
        $this->_clients[$id] = $client;
    }

    public function onDisconnect($client){
        $id = $client->getClientId();
        unset($this->_clients[$id]);
    }

    public function onData($data){
        foreach($this->_clients as $sendto){
            $sendto->send($data);
        }
    }
}

 

3.アプリケーションの登録

以下のファイルを編集し、先ほど作成したアプリケーションクラスを登録します。
lemmingzshadow-php-websocket/server/server.php

//======略=======

//WebSocketを使用するドメインとポート番号を指定します。実装する環境に合わせて指定してください。
//$server = new \WebSocket\Server('127.0.0.1', 8000, false);
$server = new \WebSocket\Server('www13137ue.sakura.ne.jp', 8000, false);

//======略=======

//ドメインを許可します。実装する環境に合わせて指定してください。
//$server->setAllowedOrigin('foo.lh');
$server->setAllowedOrigin('www13137ue.sakura.ne.jp');

//======略=======

//アプリケーションを登録します。今回は「popup」という名前で登録します。
//$server->run();の前の行に追記してください。
$server->registerApplication('popup', \WebSocket\Application\PopupApplication::getInstance());

//======略=======

※ここで指定するポート番号は、iptablesで開放しておく必要があります。

4.WebSocketサーバーを起動

先ほど編集したserver.phpを実行し、WebSocketサーバーを起動します。

$ php lemmingzshadow-php-websocket/server/server.php

以下のように表示されれば、起動成功です。

2012-10-12 17:48:33 [info] Server created

これでサーバー側の準備は完了です。

5.クライアント側の設定

手順1でダウンロードした
lemmingzshadow-php-websocket/client
ディレクトリ内のファイルを全て、ブラウザからアクセスできる場所に配置します。
そして以下のようなHTMLを、同じ場所に作成します。ここでは、popup.htmlとして作成しました。
※jQueryMobile1.2を使用しています。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style type="text/css">
      <!--
      .ui-title {overflow: visible !important; white-space: nowrap; margin:.6em 10% .8em !important;}
      -->
    </style>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
    <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
    <script>
        jQuery(function($) {
            var socket;
            //server.phpで登録したアプリケーション「popup」でWebSocketオブジェクトを生成
            socket = new WebSocket('ws://www13137ue.sakura.ne.jp:8000/popup');
            socket.onopen = function(msg) {
                $('#status').text('online');
            };
            socket.onmessage = function(msg) {
                var jmsg = $.parseJSON(msg.data);
                $('#res p').text(jmsg.data);
                $('#res').popup("open", "dialog");
            };
            socket.onclose = function(msg) {
                $('#status').text('offline');
            };

            $('#button').click(function() {
                var payload;
                payload = new Object();
                payload.action = 'echo';
                payload.data = $('#mes').val();
                return socket.send(JSON.stringify(payload));
            });
        });

    </script>
  </head>
<body>
    <div data-role="page">
      <div data-role="header">
        <h1>WebSocketからpopup</h1>
      </div>
      status:<b><span id="status"></span></b>
      <input type="text" id="mes">
      <input type="button" id="button" value="send">
      <div id="res" data-role="popup">
        <p></p>
      </div>
    </div>
</body>
</html>

WebSocketサーバが起動している状態でブラウザからアクセスし、status:onlineと表示されていればWebSocketで接続しています。
inputからテキストを送信すると、アクセスしている人全員にポップアップで表示されます。

デモはこちらです。同時に2箇所以上からご確認ください。
http://www13137ue.sakura.ne.jp/websocket/popup.html

最後に

今回はjQueryMobileのpopupを使用しましたが、チャット的な利用はもちろんバイナリデータも送受信できることから、お絵かきアプリやサウンドを使ったアプリなど、多くの用途で使えるようです。

以下の記事を参考にさせて頂きました。
使用したライブラリ同梱のサンプルアプリケーションについても、こちらで触れられています。
▼PHPでWebSocket
http://demouth.hatenablog.com/entry/20120102/1325516167

Posted in jQuery, PHP • • Top Of Page