自部門のイントラでWeb-Socketを使ってリアルタイムでデータ更新する為に
Googleで調べていましたが、決まりました。
といっても、浅い知識?(浅く広くです)なので、自分のメモです。
1、必要な要件として
  1)ie8が使える。
  2)既存のWebサーバー(WAMP)と連携出来る。
  3)Socket Server のアプリをPHPで書ける。
  4)「日本語プログラム言語なでしこ」 と連携出来る。
  ※データはテキストのみ扱います。
 これらの必須条件でいくつかのweb-socket-serverを試してみました。
 前回書いたnodejs他、各サーバーはサンプル通りに使えましたが
 ie8で使うために選択として、socket-ioかweb-socket-jsか迷いました。
 また、既存のWebはPHPで作っているのと「なでしこ」とも送受信できる・・・・
 結果として、「Devristo phpws」と「gimite web-socket-js 」 で構成する事にしました。
 決め手はPHPで書かれているうえにweb-socket-jsに対応していた事です。
 これで上記の1)、2)、3)の条件がクリア出来ました。
 「なでしこ」からweb-socket-serverへの連携はTCP-IPで出来るのでしょうが
 イロイロと試して、調べて、断念。(各種プロトコルとか・・理解不能でした!奥が深すぎる!)
 しかし、「なでしこ」のサンプルを見直したら「なでしこ」内にブラウザを部品として
 組み込めるので、その部品を経由してデータのやり取りすれば、出来る!
 これで、4)がクリア出来ます。
2、環境の構築
 「Devristo phpws」と「gimite web-socket-js 」はgithubから使わせて頂きました。
 githubの使い方は素人です、それぞれZIP形式でダウンロードして解凍しました。
  1)まず、php-web-socketですが解凍すると、phpws-masterフォルダーができます。
    中のphpwsフォルダーをxamppのhtdocsへコピー。
  2)次にweb-socket-jsの解凍、web-socket-js-masterフォルダーが出来ます。
    中の「swfobject.js」「web_socket.js」「WebSocketMain.swf」の3ファイルを
    xamppのhtdocのphpwsフォルダーへコピーします。
    これで準備完了。
3、web-socket-server起動
  1)phpwsフォルダー内のdemo.phpを見ますとPORT:12345となっています。
    機能はechoを使います。
    コマンドプロンプトで「php demo.php」で起動。
    すんなりと「Server Started」が出ました。
    ?職場で起動した時は無表示で作動してたな?(まいいか!)
  2)Apacheを起動してChromeからhttp://localhost/phpws/client.htmlを開きます。
    「WebSocket - status 0」「Welcome - status 1」が出て接続完了。
    入力欄へ文字を適当に入れてsendボタンまたはエンターでエコーを受信!。
  3)ie8からhttp://localhost/phpws/client.htmlを開きます。
    [object Error]を表示します。
    では次にweb-socket-jsですね。
4、web-socket-jsでアクセス
  1)先程の「web-socket-js-master」フォルダー内に有る「sample.html」のPORTを変更
    ws = new WebSocket("ws://localhost:10081/"); ここを12345/echoに変えて
    ws = new WebSocket("ws://localhost:12345/echo"); のsample.htmlを
    htdocs/phpwsフォルダーへ入れます。
  2)Chromeからhttp://localhost/phpws/sample.htmlを開きます。
     onopen が出て接続完了。
    入力欄へ文字を適当に入れてsendボタンまたはエンターでエコーを受信!。
  3)ie8からhttp://localhost/phpws/sample.htmlを開きます。
    「Fatal error: Call to undefined method
    WebSocketConnectionFlash::setRole()
    in C:\xampp\htdocs\phpws\websocket.protocol.php on line 18」が出て
    demo.phpが落ちました。
  4)phpwsフォルダー内のwebsocket.protocol.phpの変更
    12行目の「$s = new WebSocketConnectionFlash($socket, $data);」の下に
    return $s; を挿入して上書き保存します。
  5)コマンドプロンプトで「php demo.php」を再起動。
    ie8からhttp://localhost/phpws/sample.htmlを開きます。
     onopen が出て接続完了。
    無事に繋がってエコーも動作します。
    Chromeからも接続OK。
    コンソールのログを見比べるとChromeは自前のweb-socketで接続し
    ie8はweb-socket-jsで接続されていますね。
    「return $s;」を入れたのはソースを見てて何となく感です。
    これで本当に良いのか?
    なぜかな?。もしかして、開発した方はie8でテストしてない?
    私は自宅は「Windows-XPでie8とChrome(メイン)」
    職場では「Windows-XPでie8(メイン)とFirefox」です。
    取り敢えず動いたので次にchat機能をdemo.phpに追加します。
5、demo.phpサーバーへchat機能の追加
以下にchat追加後のソースを記載します。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/php -q
php demo.php
require_once("websocket.server.php");
/**
* This demo resource handler will respond to all messages sent to /echo/ on the socketserver below
*
* All this handler does is echoing the responds to the user
* @author Chris
*
*/
class DemoEchoHandler extends WebSocketUriHandler {
  public function onMessage(IWebSocketConnection $user, IWebSocketMessage $msg) {
   $this->say("[ECHO] " . strlen($msg->getData()) . " bytes");
   // Echo
    $user->sendMessage($msg);
   }
  public function onAdminMessage(IWebSocketConnection $user, IWebSocketMessage $obj) {
   $this->say("[DEMO] Admin TEST received!");
   $frame = WebSocketFrame::create(WebSocketOpcode::PongFrame);
  }
}
//2012.12.29 追加したchat機能
class DemoChatHandler extends WebSocketUriHandler {
  public function onMessage(IWebSocketConnection $user, IWebSocketMessage $msg) {
    $usera = $user ;
    foreach ($this->users as $user) {
     if($usera == $user){    //使い分けしたいので分離しました。
      $user->sendMessage($msg);  //送信者へエコー
     }else{
      $user->sendMessage($msg);  //送信者以外へ送信
     }
    }
  }
}
/**
* Demo socket server. Implements the basic eventlisteners and attaches a resource handler for /echo/ urls.
*
*
* @author Chris
*
*/
class DemoSocketServer implements IWebSocketServerObserver {
  protected $debug = true;
  protected $server;
  public function __construct() {
   $this->server = new WebSocketServer("tcp://0.0.0.0:12345", 'superdupersecretkey');
   $this->server->addObserver($this);
   $this->server->addUriHandler("echo", new DemoEchoHandler());
   //2012.12.29 追加したchatの呼び出し。
   $this->server->addUriHandler("chat", new DemoChatHandler());
  }
  public function onConnect(IWebSocketConnection $user) {
   $this->say("[DEMO] {$user->getId()} connected");
  }
  public function onMessage(IWebSocketConnection $user, IWebSocketMessage $msg) {
  //$this->say("[DEMO] {$user->getId()} says '{$msg->getData()}'");
  }
  public function onDisconnect(IWebSocketConnection $user) {
   $this->say("[DEMO] {$user->getId()} disconnected");
  }
  public function onAdminMessage(IWebSocketConnection $user, IWebSocketMessage $msg) {
   $this->say("[DEMO] Admin Message received!");
   $frame = WebSocketFrame::create(WebSocketOpcode::PongFrame);
   $user->sendFrame($frame);
 }
  public function say($msg) {
   echo "$msg \r\n";
  }
  public function run() {
   $this->server->run();
  }
}
// Start server
$server = new DemoSocketServer();
$server->run();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6、htmlファイルの変更
 1)chat機能を呼び出すhtmlファイルを作成
  上記、4、web-socket-jsでアクセスの1)で使った「sample.html」の
    ws = new WebSocket("ws://localhost:12345/echo"); を
    ws = new WebSocket("ws://localhost:12345/chat"); に変えてchat.htmlで保存します。
 2)ie8とChromeからhttp://localhost/phpws/chat.htmlを開きます。
     お互いにテキストのやりとりが確認出来ました!
7、日本語プログラミング言語「なでしこ」からchatへ接続
 1)上記の chat.html の78、79行目の内容を修正 id="send" id="close" を追加。
    変更前
     value="Send">
    return false;">close
    変更後
     value="Send" id="send">
    return false;" id="close">close
 2)「なでしこ」のプログラム内容
    ここでハマッタ!
    ブラウザで閲覧を改造して何となく出来そうだと思ったが
    送信は出来たが、受信のイベントをナデシコで取れない?
    chat.htmlを読み直すとスクリプトのエラーが出る。
    暫く考えます。
以上です。
0 件のコメント:
コメントを投稿