Ground Sunlight

Windowsで作る - PHPプログラミングの開発環境

ユーザ用ツール

サイト用ツール


サイドバー

メインメニュー

XAMPP アレンジ

IED

WSL2

道具箱

リポジトリ編

フレームワーク編

公開ソフトウェア

メタ
リンク


このページへのアクセス
今日: 2 / 昨日: 1
総計: 1520

ratchet:0.4:push

Ratchet Push統合

Version 0.4.3

y2sunlight 2020-11-24

Ratchet に戻る

関連記事

リンク

本章は、Ratchet 公式サイトのチュートリアル(Push to an Existing Site)のレビューです。本章は2つのパートから構成されています。



概要

問題点

これまでのチュートリアルは全てクールでしたが、開発者の焦点は、ユーザーが永続性なしでWebSocketを介して完全な対話のできるロングライフなアプリケーションを作成することです。これは、既存のサイトに組み込むには大変な作業になります。コードをリポジトリから取り出し、新しいRatchetアプリケーションに移植する必要があるかもしれません。また、以前に機能していたページが引き続き機能することを確認するには、全く新しいテストフェーズを実行する必要があるかもしれません。

目標

管理者ユーザーであれ、ブログにコメントを投稿しているユーザーであれ、ユーザーがフォーム送信(または AJAX)を介してPOSTを実行すると、その変更がそのページの他の全ての訪問者に直ぐにプッシュされるようにします。サイトへの変更はリアルタイムに行い、コードの基盤を壊したり、現在の安定性に影響に与えたりすることはしません。

このチュートリアルでは、あなたがWebサイトにブログ記事を公開していると仮定します(コードの雛形はありませんが読み取って下さい)。そして、訪問者は、あなはがそれを公開するとすぐに、その記事をポップアップ表示で見ることでしょう。

ネットワーク構成

  1. クライアントは、webサーバーに要求を行い応答を受け取り、ページをレンダリングします。その後、開いているWebSocketに対して接続を確立します。(クライアント2と3は同じことを行います)

  2. Client1 は、フォーム送信またはAJAXを介してWebサーバーにPOSTバックを実行します。(WebSocketにまだ接続してることに注意してください)

  3. webサーバーは、POSTリクエストを処理(データベースへの保存など)している間、ZeroMQトランスポートを使用してメッセージをWebSocketスタックに直接送信します。

  4. WebSocketスタックはZeroMQのメッセージを処理し、開いているWebSocket接続を介してそのメッセージを適切なクライアントに送信します。WebブラウザーはWebSocketからの着信メッセージを処理し、それに応じてWebページをJavascriptで更新します。

このワークフローは控えめで、既存のWebサイトに簡単に導入できます。サイトへの唯一の変更は、サーバーに ZeroMQ を追加し、WebSocket サーバーからの着信メッセージを処理するためにクライアントに Javascript ファイルを追加することだけです。


チュートリアルの説明

本項は、公式サイトのチュートリアル(Push to an Existing Site)の Requirement の項以降の翻訳ですが、筆者のWindows環境(PHP7.2.22)では、再現することができませんでした。

その原因は、PHPのCLI版では正常に動作した ZeroMQ が Apache を介したPHP拡張モジュールとし動作しなかったからです。phpinfo()でも ZeroMQ のロードが確認出来ており、ZMQSocket はパースエラーもなくそのインスタンスは正常に作成できていたにも関わらず、ZMQSocketのsend()メソッドが働きませんでした。この現象につき情報をお持ちの方は、お手数でもコメント頂戴できれば幸いです。

従って、本項はチュートリアルの翻訳だけに留め、その代替案として ZeroMQ ではなくて、PHPのソケット関数を使いチュートリアルを実行しました。その実装方法については、次章「チュートリアルの実行」を参照して下さい。

尚、ZeroMQのPHP拡張モジュールのWindowsバイナリは現段階でPHP7.2までしか正式に公開されていませんでしたので、PHP7.2.22の環境下でテストしております。(2020-11-25時点)


要件

ZeroMQ

実行中のスクリプトと通信するには、開いているソケットでリッスンしている必要があります。私たちのアプリケーションは、着信中の WebSocket 接続のポート8080をリッスンしますが、他のPHPスクリプトからの更新も取得するにはどうすればよいでしょうか。ZeroMQ|ZeroMQ を使いましょう。Ratchetを構築しているようなrawソケットを使用することもできますが、ZeroMQは、簡単にソケットだけを作ってくれるライブラリです。

ZeroMQは、ライブラリー(libzmq)であり、それはPHPバインディング用のPECL拡張機能と同様にインストールする必要があります。インストールは簡単で、多くのオペレーティングシステム用のものがWebサイトで提供されています。

ZeroMQのインストール方法は以下を参照して下さい。

ZeroMQのPHP拡張モジュールのWindowsバイナリは現段階でPHP7.2までしか正式に公開されていません。(2020-11-25時点)

React/ZMQ

Ratchet は、React と呼ばれるソケットライブラリの上に構築された WebSocket ライブラリです。React は、接続と Ratchet に対する raw I/O を処理します。私達は Ratchet に付属している React に加えて、React スイートの一部である別のライブラリ React/ZMQ が必要となります。このライブラリは、ZeroMQ ソケットをReactorコアにバインドし、WebSocket と ZeroMQ ソケットの両方を処理できるようにします。

React/ZMQ をインストールするための composer.json ファイルについては次項を参照して下さい。


コーディングの開始

さあコードに取り掛かりましょう! まず、アプリケーション スタブクラスから始めます。ここでは、Pub/Subパターンでの使いやすさのためにWAMP( WampServerInterface )を使用します。これにより、クライアントは特定のページの更新を購読でき、購読しているユーザーにのみ更新をプッシュします。

Pusher.php
<?php
namespace MyApp;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
 
class Pusher implements WampServerInterface {
    public function onSubscribe(ConnectionInterface $conn, $topic) {
    }
    public function onUnSubscribe(ConnectionInterface $conn, $topic) {
    }
    public function onOpen(ConnectionInterface $conn) {
    }
    public function onClose(ConnectionInterface $conn) {
    }
    public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
        // In this application if clients send data it's because the user hacked around in console
        // このアプリケーションでは、クライアントがデータを送信する場合、それはユーザーがコンソールでハッキングしたためです
        $conn->callError($id, $topic, 'You are not allowed to make calls')->close();
    }
    public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
        // In this application if clients send data it's because the user hacked around in console
        $conn->close();
    }
    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

これを /src/Pusher.php に保存します。WAMPに必要なメソッドを作成し、誰からもデータを送信されないようにし、送信された場合はその接続を閉じます。ここでは、プッシュアプリケーションを作成しており、WebSocketからの受信メッセージは受け付けていません。これらのメッセージはすべてAJAXから送信されます。


ブログ送信の編集

次に、新しいブログ投稿を処理する既存のWebサイトのコードに ZeroMQ のおまじないを少し追加します。ここでのコードは、あなたが実際にブログで設置している Drupal や WordPress のような高度なアーキテクチャと比較すると、少し基本的で古風なものかもしれませんが、ここでは基本的なことに焦点を当てています。

<?php
    // post.php ???
    // This all was here before  ;)
    $entryData = array(
        'category' => $_POST['category']
      , 'title'    => $_POST['title']
      , 'article'  => $_POST['article']
      , 'when'     => time()
    );
 
    $pdo->prepare("INSERT INTO blogs (title, article, category, published) VALUES (?, ?, ?, ?)")
        ->execute($entryData['title'], $entryData['article'], $entryData['category'], $entryData['when']);
 
    // This is our new stuff
    $context = new ZMQContext();
    $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
    $socket->connect("tcp://localhost:5555");
 
    $socket->send(json_encode($entryData));

ブログ投稿をデータベースに記録した後、ソケットサーバーへの ZeroMQ 接続を開き、投稿と同じ情報を含むシリアル化されたメッセージを配信します。(注:適切な消毒を行ってください。これはとりあえずの汚い例です)


ZeroMQ メッセージの処理

アプリケーションスタブクラスに戻りましょう。そのままにしておくと、WebSocket 接続のみを処理することになります。前回のコードスニペットで見たように、データを送信するポート 5555 でローカルホストへの接続を開きました。ZeroMQメッセージに対する処理を追加し、WebSocketクライアントに再送信するようにしましょう。

<?php
namespace MyApp;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
 
class Pusher implements WampServerInterface {
    /**
     * A lookup of all the topics clients have subscribed to
     * クライアントが購読している全てのトピックの探索配列
     */
    protected $subscribedTopics = array();
 
    public function onSubscribe(ConnectionInterface $conn, $topic) {
        $this->subscribedTopics[$topic->getId()] = $topic;
    }
 
    /**
     * @param string JSON'ified string we'll receive from ZeroMQ
     */
    public function onBlogEntry($entry) {
        $entryData = json_decode($entry, true);
 
        // If the lookup topic object isn't set there is no one to publish to
        // トピック探索オブジェクトがセットされていない場合、公開する相手はありません
        if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
            return;
        }
 
        $topic = $this->subscribedTopics[$entryData['category']];
 
        // re-send the data to all the clients subscribed to that category
        // そのカテゴリを購読している全てのクライアントにデータを再送信します
        $topic->broadcast($entryData);
    }
 
    /* The rest of our methods were as they were, omitted from docs to save space
       残りのメソッドはそのままで、スペースを節約するためにドキュメントから省略しました
    */
}


全てを結合する

これまで、メッセージの送信、受信、および処理のすべてのロジックについて説明してきました。次に、すべてを結合して、すべてを管理する実行可能なスクリプトを作成します。I/O、WebSocket、WAMP、ZeroMQ の各コンポーネントを使用してRatchetアプリケーションを構築し、イベントループを実行します。

<?php
    require dirname(__DIR__) . '/vendor/autoload.php';
 
    $loop   = React\EventLoop\Factory::create();
    $pusher = new MyApp\Pusher;
 
    // Listen for the web server to make a ZeroMQ push after an ajax request
    // ajaxリクエストの後にZeroMQプッシュを行うためにWebサーバーをリッスンします
    $context = new React\ZMQ\Context($loop);
    $pull = $context->getSocket(ZMQ::SOCKET_PULL);
    $pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
    $pull->on('message', array($pusher, 'onBlogEntry'));
 
    // Set up our WebSocket server for clients wanting real-time updates
    // リアルタイム更新が必要なクライアント向けにWebSocketサーバーをセットアップします
    $webSock = new React\Socket\Server('0.0.0.0:8080', $loop); // Binding to 0.0.0.0 means remotes can connect
    $webServer = new Ratchet\Server\IoServer(
        new Ratchet\Http\HttpServer(
            new Ratchet\WebSocket\WsServer(
                new Ratchet\Wamp\WampServer(
                    $pusher
                )
            )
        ),
        $webSock
    );
 
    $loop->run();

コードを /bin/push-server.php として保存し、実行します。

$ php bin/push-server.php


クライアントサイド

サーバーサイドのコードが完成し、稼働しているので、これらのリアルタイムの投稿を取得する時が来ました!これらの更新で具体的に何を行うのかは、このドキュメントの範囲を超えています。これらのメッセージをデバッグコンソールに出力するだけにします。

<script src="https://gist.githubusercontent.com/cboden/fcae978cfc016d506639c5241f94e772/raw/e974ce895df527c83b8e010124a034cfcf6c9f4b/autobahn.js"></script>
<script>
    var conn = new ab.Session('ws://localhost:8080',
        function() {
            conn.subscribe('kittensCategory', function(topic, data) {
                // This is where you would add the new article to the DOM (beyond the scope of this tutorial)
                // ここで、新しい記事をDOMに追加します(これは、このチュートリアルの範囲を超えています)
                console.log('New article published to category "' + topic + '" : ' + data.title);
            });
        },
        function() {
            console.warn('WebSocket connection closed');
        },
        {'skipSubprotocolCheck': true}
    );
</script>

最後に、このJavascriptを配置したページを1つのブラウザウィンドウで開き、別のブラウザから「kittensCategory」にブログエントリを投稿して、最初からコンソールのログを確認します。それが機能していたら、次のステップは、受信したデータを操作性の良いDOMの中に組み込むことです。

これがローカルで機能している場合(ローカルホストが開発環境であると想定)、ローカルホストの参照と、場合によっては適切なサーバーホスト名/IPアドレスへの結合を変更することができます。


チュートリアルの実行

本項ではチュートリアルの実行について説明します。前項でも述べたように、筆者の環境では ZeroMQ を使った実装がWindowsで出来なかったので、以下の環境に変更してチュートリアルの実行を行いました。

  • サーバ側は、React\ZMQ から React\Socket に変更(ZeroMQ でなくて、rawソケットを使用)
  • ブログポストからは ZeroMQ によるプッシュを PHPのソケット関数に変更
  • ZeroMQ を使わないので、PHPは7.2から7.3に変更

以下では、実行で使用したプロジェクトとソースコードを掲載しますが、変更点以外は、前項のチュートリアルの説明と同じです。


プロジェクトの作成

まず、プロジェクトフォルダ(以下 {Project-Folder} と呼びます)を作成し、そこにComposerファイルを設置します。

composer.json
{
    "autoload": {
        "psr-4": {
            "MyApp\\": "src"
        }
    },
    "require": {
        "cboden/ratchet": "^0.4"
    }
}

上の設定では、プロジェクトフォルダ下の src フォルダにアプリケーションを設置し、そこを MyApp 名前空間として定義します。 Composer の規則に従い、ratchet は vender/cboden/ratchet の下に保存されます。

また、プロジェクトフォルダ下に以下のフォルダを作成します:

  • bin — WebSocketsサーバー用のスクリプトを格納します(CLIモード)
  • src — Pusherクラスを格納します
  • blog — ブログ側のソースコード一式

準備が出来たら、コマンドプロンプトでプロジェクトフォルダに移動して、composer install を実行します。


WebSockサーバー

以下のWebSockサーバーを {Project-Folder}/bin の下に配置します。

{Project-Folder}/bin/push-server.php

push-server.php
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
 
use React\EventLoop\Factory;
use React\Socket\ConnectionInterface;
use React\Socket\Server;
 
$pusher = new MyApp\Pusher;
$ws_port = '0.0.0.0:8080';       // WebSocketサーバー (0.0.0.0は公開を表す)
$pusher_port = '127.0.0.1:5555'; // プッシュ用のメッセージ受信ソケット(ローカル用)
 
// イベントループの作成
$loop = Factory::create();
 
// リアルタイム更新が必要なクライアント向けにWebSocketサーバーをセットアップします。
// リアルタイム更新を待ちます
$webSock = new React\Socket\Server($ws_port, $loop);
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
        new Ratchet\WebSocket\WsServer(
            new Ratchet\Wamp\WampServer(
                $pusher
                )
            )
        ),
    $webSock
    );
 
// プッシュ用のメッセージ受信のために着信TCPソケットをセットアップします。
// postメッセージがrawソケットを使って、このTCPポートに送信されてきます
$inSocket = new Server($pusher_port, $loop);
$inSocket->on('connection', function (ConnectionInterface $conn) use ($pusher) {
    // ソケットでメッセージを受信した時
    $conn->on('data', function ($data) use ($conn, $pusher) {
        //ブログ投稿の更新をプッシュします
        $pusher->onBlogEntry($data);
        $conn->close();
    });
});
 
// イベントループ
$loop->run();
  • 前半のWebSocketサーバーのセットアップの部分はオリジナルのコードと同じです。
  • 後半部分は、プッシュ用のメッセージ受信のために着信TCPソケットをセットアップし、それをWebSocketサーバーと同じイベントループで処理しています。
  • プッシュ用のメッセージを受信した時、Pusher の onBlogEntry() を明示的に呼び出しています。

Pusherクラスについては、デバッグライトを追加した以外は、オリジナルのコードと同じです。これは、{Project-Folder}/src に配置します。

{Project-Folder}/src/Pusher.php

Pusher.php
<?php
namespace MyApp;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\WampServerInterface;
 
class Pusher implements WampServerInterface {
    /**
     * クライアントが購読している全てのトピックの探索配列
     */
    protected $subscribedTopics = array();
 
    public function onSubscribe(ConnectionInterface $conn, $topic) {
        echo "onSubscribe({$conn->remoteAddress},{$conn->resourceId},'{$topic->getId()}')\n";
        $this->subscribedTopics[$topic->getId()] = $topic;
    }
 
    /**
     * @param string ZeroMQから受信したJSON化された文字列
     */
    public function onBlogEntry($entry) {
        echo "onBlogEntry():\n";
        $entryData = json_decode($entry, true);
 
        // トピック探索オブジェクトがセットされていない場合、公開する相手はありません
        if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
            return;
        }
 
        $topic = $this->subscribedTopics[$entryData['category']];
 
        // そのカテゴリを購読している全てのクライアントにデータを再送信します
        $topic->broadcast($entryData);
        echo json_encode($entryData)."\n";
    }
 
    public function onUnSubscribe(ConnectionInterface $conn, $topic) {
        echo "onUnSubscribe({$conn->remoteAddress},{$conn->resourceId})\n";
    }
    public function onOpen(ConnectionInterface $conn) {
        echo "onOpen({$conn->remoteAddress},{$conn->resourceId})\n";
    }
    public function onClose(ConnectionInterface $conn) {
        echo "onClose({$conn->remoteAddress},{$conn->resourceId})\n";
    }
    public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {
        echo "onCall({$conn->remoteAddress},{$conn->resourceId})\n";
        // このアプリケーションでは、クライアントがデータを送信する場合、それはユーザーがコンソールでハッキングしたためです
        $conn->callError($id, $topic, 'You are not allowed to make calls')->close();
    }
    public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {
        echo "onPublish({$conn->remoteAddress},{$conn->resourceId})\n";
        // このアプリケーションでは、クライアントがデータを送信する場合、それはユーザーがコンソールでハッキングしたためです
        $conn->close();
    }
    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "onError({$conn->remoteAddress},{$conn->resourceId})\n";
    }
}


ブログ投稿ページ

新しいブログ投稿を処理する為のコードは、新規に作成し直しました。このコードは {Project-Folder}/blog に配置します。

{Project-Folder}/blog/entry.php

entry.php
<?php
putenv('app-version=1.0.0');
 
if ($_SERVER ['REQUEST_METHOD'] === 'POST')
{
    $entryData = array(
        'category' => $_POST['category']
        , 'title'    => $_POST['title']
        , 'article'  => $_POST['article']
        , 'when'     => time()
    );
 
    $instance = stream_socket_client('tcp://127.0.0.1:5555');
    fwrite($instance, json_encode($entryData));
 
    header("Location: {$_SERVER['REQUEST_URI']}");
    exit();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Blog Stab</title>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <!-- javascript -->
    <script src="js/autobahn.js"></script>
    <script src="js/main.js?v=<?php echo getenv('app-version')?>"></script>
 
</head>
<body>
    <main class="mt-3 mb-5">
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-12">
<?php include('template/entry.template.php')?>
                </div>
            </div>
            <div class="mt-2">
                <dl id="new-articles"><dl>
            </div>
        </div>
    </main>
</body>
</html>
  • ブログが投稿された時(POSTメソッドでは)、WebSocketサーバーへPHPのソケット関数(stream_socket_client)を使い、メッセージを送信しています。

  • GETメソッドでこのスクリプトが呼び出された場合は、投稿用のHTMLをレンダリングします:
    • ブラウザ表示用のフレームワークとしてbootstrapを使用しています。
    • 投稿ページは entry.template.php に保存されているものを include() して使用します。


クライアントサイド

クライアントサイドのメインのソースコードは上に掲載した entry.php 内のHTMLです。メインで使っている他のソースコードは以下の通りです。

  • template/entry.template.php — ブログ投稿画面のHTML
  • js/main.js — WebSocketとの接続、購読を行うJavaScript
  • js/autobahn.js — WAMP(V1)のJavaScriptライブラリー

以下は、ブログ投稿画面のHTMLです。このコードは {Project-Folder}/blog/template に配置します。

{Project-Folder}/blog/template/entry.template.php

entry.template.php
<h1>Blog Entry</h1>
<form method="POST" name="fm">
 
    <div class="form-group row">
        <label for="category" class="col-md-2 col-form-label">Category</label>
        <div class="col-md-10">
            <select name="category" id="category" class="form-control" required>
                <option value="kittensCategory">kittensCategory</option>
                <option value="category2">Category2</option>
                <option value="category3">Category3</option>
            </select>
        </div>
    </div>
 
    <div class="form-group row">
        <label for="title" class="col-md-2 col-form-label">Title</label>
        <div class="col-md-10">
            <input type="text" name="title" id="title" class="form-control" required>
        </div>
    </div>
 
    <div class="form-group row">
        <label for="article" class="col-md-2 col-form-label">Article</label>
        <div class="col-md-10">
            <textarea name="article" id="article" class="form-control" required></textarea>
        </div>
    </div>
 
    <div class="mt-4">
        <input type="submit" id="btn_submit" class="btn btn-primary">
    </div>
 
</form>

以下は、WebSocketとの接続、購読を行うJavaScriptです。このコードは {Project-Folder}/blog/js に配置します。

{Project-Folder}/blog/js/main.js

main.js
/*
 * Subscribe Session
 */
var conn = new ab.Session('ws://localhost:8080',
    function() {
        conn.subscribe('kittensCategory', function(topic, data) {
            console.log('New article published to category "' + topic + '" : ' + data.title);
            $('#new-articles').prepend('<dt>'+data.title+'</dt><dd>'+data.article+'</dd>');
        });
    },
    function() {
        console.warn('WebSocket connection closed');
    },
    {'skipSubprotocolCheck': true}
);
  • ページロード時に、WebSocketサーバー( ws://localhost:8080 )に接続し「kittensCategory」の購読を開始します。
  • 他のユーザが「kittensCategory」のブログを投稿した時、#new-articles のIDを持つHTML要素に対して、定義リスト(DL)を追加します。

WAMP(V1)について

WAMP(V1)のJavaScriptライブラリーは、以下に設置します:

{Project-Folder}/blog/js/autobahn.js

このライブラリーは、以下より取得して設置しました。

https://gist.githubusercontent.com/cboden/fcae978cfc016d506639c5241f94e772/raw/e974ce895df527c83b8e010124a034cfcf6c9f4b/autobahn.js

この autobahn.js は、WAMP のバージョン1対応のライブラリです。Ratchet は WAMP のバージョン2をサポートしていないので、敢えて AutobahnJS の古いライブラリーを使用しています。

補足

WAMPとは WebSocket Application Messaging Protocol の略で、次の機能を提供するWebSocketのサブプロトコルです。

  • ルーティングされたリモートプロシージャコール
  • パブリッシュ & サブスクライブ

詳しくは以下を参照:


プログラムの実行

コマンドプロンプトでプロジェクトフォルダに移動してWebSocketサーバーを起動します。

php bin/push-server.php

ブラウザで entry.php を2つのブラウザーからアクセスします。一方のブラウザでプログを投稿すると、その内容は他方のブラウザに表示されます。


コメント

test27.153.185.229, 2022/11/16 05:06

https://www.nikeoutletstoreclearance.us.com/ https://www.pandora-jewelryrings.us/ https://www.nikebasketball-shoes.us.com/ https://www.airjordan1mid.us.com/ https://www.nikeair-jordan.us.com/ https://www.airforce-1.us.org/ https://www.new-nikeshoes.us.com/ https://www.airjordan11.us.org/ https://www.nikeshoesclearance.us.com/ https://www.nikestorefactory.us.com/ https://www.menwomenshoes.us/ https://www.jordanaj1.us.com/ https://www.jordanretroshoes.us.org/ https://www.air-jordansretro.us.com/ https://www.nikefreerun.us.org/ https://www.airjordan14.us.com/ https://www.newshoes2019.us/ https://www.christianslouboutin.us.com/ https://www.jewelrynecklacerings.uk.com/ https://www.nike-basketballshoes.us.org/ https://www.nikerunning-shoes.us.com/ https://www.pandoracom.ca/ https://www.fjallravenkankenbackpack.us/ https://www.nikeair-max.us.org/ https://www.yeezy500.us.org/ https://www.jordans13retro.us/ https://www.max97trainers.uk.com/ https://www.newnikeshoes.us.org/ https://www.nikeoutlet-factory.us.com/ https://www.adidasultra-boosts.us.com/ https://www.nikes-sneakers.us.com/ https://www.airmax2019.us.org/ https://www.red-bottomshoesforwomen.us.com/ https://www.airjordan-retro11.us.com/ https://www.christianlouboutins.us.org/ https://www.shoesyeezy.us.com/ https://www.pandoracanadajewelrycharms.ca/ https://www.nikefactory-outlet.us.org/ https://www.kyrie-irvingshoes.us.org/ https://www.pandorasjewelryoutlet.us.com/ https://www.nikeshoescybermondayblackfriday.us.com/ https://www.nmdr1adidas.us.com/ https://www.pandorascharm.us.com/ https://www.nike-outletstores.us.com/ https://www.pandorabracelets-clearance.us.com/ https://www.jordansretro11.us.com/ https://www.jordansretro13.us.com/ https://www.airjordans.com.co/ https://www.pandoras.us.org/ https://www.christianlouboutinshoessaleoutlet.us/ https://www.louboutinshoess.us/ https://www.nikefactorystoreonline.us.com/ https://www.pandorabraceletsforwomen.us/ https://www.nike-stores.us.org/ https://www.shoes-yeezy.us.com/ https://www.nikeoutletstores.us.org/ https://www.jordan11gammablue.us/ https://www.newjordanscomingout.us.com/ https://www.runningshoesformenwomen.us/ https://www.nikefactorys.us/ https://www.nikeshoesfactorys.us.com/ https://www.nikeoutletonline-store.us.com/ https://www.ultra-boosts.us.com/ https://www.sneakerswebsite.us/ https://www.valentinoshoessale.us.com/ https://www.nikecortez.us.org/ https://www.air-jordans1.us.com/ https://www.jewelrycharmsrings.uk.com/ https://www.ferragamobelts.us.com/ https://www.airmax-98.us.com/ https://www.louboutinheelsshoes.us.com/ https://www.jordan1s.us.org/ https://www.air-max95.us.com/ https://www.vansshoes-outlets.us.com/ https://www.moncleroutletuk.uk.com/ https://www.redbottomshoes-forwomen.us/ https://www.golden-gooses.us.com/ https://www.air-jordan8.us.com/ https://www.christian-louboutinoutletsale.us.com/ https://www.outletstoreonlineshopping.us/ https://www.nikeoutletstoreonlines.us.com/ https://www.jordan4s.us.com/ https://www.yeezys-adidas.us.com/ https://www.charmsbracelet.uk.com/ https://www.nikeairmax720.us.com/ https://www.airjordan9.us.com/ https://www.ferragamosshoes.us.com/ https://www.jordan7.us.com/ https://www.nikeairmax720.us.org/ https://www.pandorajewelryofficialwebsite.us/ https://www.cheapnikesshoes.us.com/ https://www.nikeairzooms.us.com/ https://www.nikeshoes2019.us.com/ https://www.christian-louboutin-shoes.us.org/ https://www.nike-clearance.us.com/ https://www.pandoracharmscom.us/ https://www.christianlouboutins.uk.com/ https://www.nike--shoes.us.com/ https://www.jordansshoesformen.us.com/ https://www.pandorascharmsjewelry.us/ https://www.nikeshoesonlines.us.com/ https://www.nikesneakersoutlet.us.org/ https://www.nikehuaraches.us.com/ https://www.michael-jordanshoes.us.com/ https://www.yeezyboosts-350.us.com/ https://www.uncjordan1.us.com/ https://www.fjallravenbackpack.us/ https://www.nikecortezshox.us.com/ https://www.adidas-nmds.us.org/ https://www.yeezyshoess.us.com/ https://www.airjordanshoesretros.us.com/ https://www.nikeshoesshop.us.com/ https://www.jordanshoesforkids.us/ https://www.nike-outletstoreonlineshopping.us.com/ https://www.nikeairforce.us.org/ https://www.airjordans-sneakers.us/ https://www.nikefreernrun.us.com/ https://www.jordan32shoes.us/ https://www.yeezyscheap.us.com/ https://www.jordan3.us.com/ https://www.pandora-earrings.us/ https://www.lebronjamesshoessale.us.com/ https://www.nike-airmax98.us/ https://www.nikestores.us.org/ https://www.charmsjewelryrings.uk.com/ https://www.kyrieirvingbasketballshoes.us.com/ https://www.christianlouboutins-outlet.us.com/ https://www.yeezysboosts.us.com/ https://www.redbottomslouboutinshoes.us/ https://www.airjordanssneakers.us.org/ https://www.adidassneakers.us.com/ https://www.kevin-durantsshoes.us.com/ https://www.pandorashop.ca/ https://www.nikeoutletstore-onlineshopping.us.org/ https://www.jewelrycharms.us/ https://www.nikeshoesfactorystore.us.com/ https://www.jordan-retro4.us.com/ https://www.nikereactuptempo.us.com/ https://www.nike-presto.us.com/ https://www.nikeair-max270.us/ https://www.nike-jordan1.us.com/ https://www.jordan12s.us.com/ https://www.asicsshoesoutlet.us.com/ https://www.lebron16shoes.us.org/ https://www.airforce1shoes.us.com/ https://www.lebron16shoes.us/ https://www.nikeoutletonlineclearance.us.com/ https://www.nikeshoess.us.org/ https://www.red-bottomheels.us/ https://www.nike-zoom.us.com/ https://www.nikeoutletstoreonline-shopping.us.com/ https://www.air-jordan10.us.com/ https://www.nikesclearance.us/ https://www.jordan1high.us.com/ https://www.pandoranecklaces.us/ https://www.nike-runningshoes.us/ https://www.airforceones.us.com/ https://www.nikesneakerssale.us.com/ https://www.lebron-jamesshoes.us.org/

test110.82.137.23, 2023/03/17 18:41

https://www.yeezys-shoes.us.org/ https://www.nike-jordans.us.com/ https://www.balenciagatriples.us.org/ https://www.ggdbshoes.us.com/ https://www.nikesoutletstoreonlineshopping.us.com/ https://www.newjordan11.us/ https://www.air-jordansneakers.us/ https://www.jordan-retro1.us.com/ https://www.jordan14.us.com/ https://www.pandorasjewelry.us.com/ https://www.shoeslouboutin.us.com/ https://www.christian-louboutinheels.us.com/ https://www.jordans5.us/ https://www.pandorascharms.us.com/ https://www.louboutinshoesheels.us.com/ https://www.jamesharden-shoes.us.org/ https://www.nikefactoryoutlets.us.org/ https://www.fitflop-shoes.us.org/ https://www.yeezy.us.org/ https://www.jordans-11.us/ https://www.jordan-retro6.us/ https://www.soccercleats.us.com/ https://www.retrosairjordan.us/ https://www.jordan-shoesformen.us.com/ https://www.ggdbs.us.com/ https://www.air-jordan12.us/ http://www.pandorarings.us.com/ https://www.nikeoutletfactorys.us.com/ https://www.airmax-95.us.com/ https://www.outletnikestore.us.com/ https://www.monclercom.us.com/ https://www.airjordan6rings.us/ https://www.outletgoldengoose.us.com/ https://www.nikeshoesoutletfactory.us.com/ https://www.jordansneakerss.us/ https://www.pandorajewelryofficial-site.us/ https://www.nikesnkrs.us.com/ https://www.jordan-12.us.com/ https://www.air-jordanssneakers.us/ https://www.airjordanshoess.us.com/ https://www.jordan1.us.com/ https://www.airjordanretro11.us.com/ https://www.airforceoneshoes.us.com/ https://www.balenciagaofficial.us.com/ https://www.vanscom.us.com/ https://www.adidasyeezysneakers.us.com/ https://www.jordans4retro.us/ https://www.ggdbsneakers.us.com/ https://www.goldengooseoutletfactory.us.com/ https://www.jordan10.us.com/ https://www.goldengoosessneakers.us.com/ https://www.air-max90.us.com/ https://www.goldensgoose.us.com/ https://www.jordan-8.us/ https://www.redbottomslouboutin.us.org/ https://www.nikeairjordan.us.com/ https://www.airjordan3s.us/ https://www.airjordan11s.us.com/ https://www.eccos.us.com/ https://www.pandoras.us.com/ https://www.newnikeshoes.us.com/ https://www.air-jordan1s.us.com/ https://www.nikeair-jordan1.us.com/ https://www.jordan11ssneakers.us/ https://www.jordan12retros.us/ https://www.jordanretros.us.com/ https://www.jordans11.us.com/ https://www.goldengoosesales.us.com/ https://www.redbottomshoesforwomen.us.com/ https://www.jordansretro3.us/ https://www.jordans1s.us.com/ https://www.newjordansshoes.us.com/ https://www.airjordan5.us/ https://www.jordan13.us.org/ https://www.monclerjacketsstore.us.com/ https://www.airjordan1s.us.org/ https://www.airmax270s.us.com/ https://www.air-jordan4.us.com/ https://www.birkin-bag.us.com/ https://www.jordan11sshoes.us/ https://www.air-jordans11.us.com/ https://www.airmax270.us.org/ https://www.canadapandoracharms.ca/ https://www.nikesfactory.us.com/ https://www.jordan11red.us.com/ https://www.jordans1.us.com/ https://www.nikeoutletstoresonlineshopping.us.com/ https://www.mensnikeshoes.us.com/ https://www.jordan13s.us/ https://www.adidasyeezysshoes.us.com/ https://www.pandoraringssite.us/ https://www.airjordan4s.us/ https://www.nikeairmax98.us/ https://www.nike-airmax2018.us.com/ https://www.christianslouboutin.uk.com/ https://www.nikeshoes-cheap.us.com/ https://www.adidasnmdr1.us.org/ https://www.airjordansneakers.us.com/ https://www.nikeshoesforwomens.us.com/ https://www.new-jordans.us.com/ https://www.goldengoosesneakerss.us.com/ https://www.asics-running-shoes.us.com/ https://www.jordanretro11mens.us/ https://www.sneakersgoldengoose.us.com/ https://www.christianlouboutinshoesinc.us.com/ https://www.air-jordan6.us/ https://www.jordan9.us.com/ https://www.jacketsmoncleroutlet.us.com/ https://www.nikesales.us.com/ https://www.nmds.us.com/ https://www.kyrieirving-shoes.us.org/ https://www.coatsmoncler.us.com/ https://www.pandoraonline.us/ https://www.pandorajewelryofficialsite.us.com/ https://www.jordans-sneakers.us.com/ https://www.jordanshoess.us.com/ https://www.nikeair-maxs.us.com/ https://www.jordan1universityblue.us.com/ https://www.christianslouboutinshoes.us.com/ https://www.jordanshoesretro.us.com/ https://www.pandora-braceletcharms.us/ https://www.goldengooseshoess.us.com/ https://www.ferragamos.us.org/ https://www.huarachesnike.us.com/ https://www.jordanscheapshoes.us/ https://www.jordan5.us.com/ https://www.jordan12retro.us.com/ https://www.valentinosshoes.us.org/ https://www.monclerstores.us.com/ https://www.yeezys.com.co/ https://www.nike--shoes.us.com/ https://www.jordan-4.us.com/ https://www.nikeofficialwebsite.us.com/ https://www.retro-jordans.us/ https://www.pandoracanadajewelry.ca/ https://www.nikeairmax-shoes.us.com/ https://www.lebron-shoes.us.com/ https://www.monclervest.us.com/ https://www.jordan11low.us.com/ https://www.nikeoutletshoes.us.com/ https://www.redbottomshoeslouboutin.us.com/ https://www.airjordansnew.us.com/ https://www.retrosjordans.us/ https://www.yeezys-shoes.us.com/ https://www.pandorajewellery.us.com/ https://www.jordansshoesforsale.us.com/ https://www.fjallraven-kanken.us.com/ https://www.jordansretro12.us/ https://www.jordans-4.us/ https://www.air-jordan6.us.com/ https://www.jordan1lows.us.com/ https://www.jordanretro-11.us.com/ https://www.goldengoosemidstar.us.com/ https://www.yeezyonline.us.com/

test59.60.126.152, 2023/03/23 12:56

https://www.jordanretros.us.com/ https://www.retrosjordans.us/ https://www.fjallraven-kanken.us.com/ https://www.jordan9.us.com/ https://www.monclervest.us.com/ https://www.air-max90.us.com/ https://www.jacketsmoncleroutlet.us.com/ https://www.nikesales.us.com/ https://www.newjordan11.us/ https://www.airjordan11s.us.com/ https://www.ggdbshoes.us.com/ https://www.jordansretro3.us/ https://www.pandorajewellery.us.com/ https://www.monclerjacketsstore.us.com/ https://www.airjordan4s.us/ https://www.jordan-retro6.us/ https://www.ferragamos.us.org/ https://www.jordan14.us.com/ https://www.adidasnmdr1.us.org/ https://www.jordan12retros.us/ https://www.christianslouboutinshoes.us.com/ https://www.jordan-12.us.com/ https://www.jordanshoess.us.com/ https://www.adidasyeezysneakers.us.com/ https://www.jordan5.us.com/ https://www.airjordan1s.us.org/ https://www.huarachesnike.us.com/ https://www.soccercleats.us.com/ https://www.nikeairmax98.us/ https://www.jordans4retro.us/ https://www.asics-running-shoes.us.com/ https://www.pandora-braceletcharms.us/ https://www.jamesharden-shoes.us.org/ https://www.nikeoutletfactorys.us.com/ https://www.yeezys.com.co/ https://www.jordan1.us.com/ https://www.ggdbs.us.com/ https://www.nikeairjordan.us.com/ https://www.newjordansshoes.us.com/ https://www.jordan13.us.org/ https://www.balenciagaofficial.us.com/ https://www.redbottomshoeslouboutin.us.com/ https://www.vanscom.us.com/ https://www.pandorasjewelry.us.com/ https://www.airmax-95.us.com/ https://www.christianlouboutinshoesinc.us.com/ https://www.louboutinshoesheels.us.com/ https://www.jordans-sneakers.us.com/ https://www.goldengoosemidstar.us.com/ https://www.yeezys-shoes.us.org/ https://www.airmax270s.us.com/ https://www.sneakersgoldengoose.us.com/ https://www.canadapandoracharms.ca/ https://www.jordansretro12.us/ https://www.airjordan5.us/ https://www.air-jordan6.us.com/ https://www.pandorascharms.us.com/ https://www.jordan1universityblue.us.com/ https://www.christian-louboutinheels.us.com/ https://www.goldengoosesales.us.com/ https://www.jordans-11.us/ https://www.jordan-8.us/ https://www.coatsmoncler.us.com/ https://www.jordanscheapshoes.us/ https://www.jordanretro-11.us.com/ https://www.nikeairmax-shoes.us.com/ https://www.nikeoutletshoes.us.com/ https://www.jordanshoesretro.us.com/ https://www.airforceoneshoes.us.com/ https://www.jordans-4.us/ https://www.redbottomshoesforwomen.us.com/ https://www.jordan11sshoes.us/ https://www.redbottomslouboutin.us.org/ https://www.nikeshoes-cheap.us.com/ https://www.nikefactoryoutlets.us.org/ https://www.jordans11.us.com/ https://www.nikeair-maxs.us.com/ https://www.nikeshoesforwomens.us.com/ https://www.pandoraringssite.us/ https://www.nike-airmax2018.us.com/ https://www.air-jordansneakers.us/ https://www.airjordan6rings.us/ https://www.goldengooseshoess.us.com/ https://www.goldengoosesneakerss.us.com/ https://www.air-jordans11.us.com/ https://www.kyrieirving-shoes.us.org/ https://www.birkin-bag.us.com/ https://www.air-jordan1s.us.com/ https://www.jordan1lows.us.com/ https://www.outletgoldengoose.us.com/ https://www.nikeshoesoutletfactory.us.com/ https://www.ggdbsneakers.us.com/ https://www.nikesnkrs.us.com/ https://www.jordans1s.us.com/ https://www.jordan-retro1.us.com/ https://www.monclerstores.us.com/ https://www.yeezy.us.org/ https://www.nike-jordans.us.com/ https://www.jordan11ssneakers.us/ https://www.newnikeshoes.us.com/ https://www.air-jordan12.us/ https://www.pandorajewelryofficial-site.us/ https://www.airjordansnew.us.com/ https://www.pandoraonline.us/ https://www.airjordanretro11.us.com/ https://www.nikesoutletstoreonlineshopping.us.com/ https://www.nikeair-jordan1.us.com/ https://www.jordans1.us.com/ https://www.balenciagatriples.us.org/ https://www.goldengoosessneakers.us.com/ https://www.jordanretro11mens.us/ https://www.jordan-shoesformen.us.com/ https://www.monclercom.us.com/ https://www.air-jordan6.us/ https://www.goldengooseoutletfactory.us.com/ https://www.yeezys-shoes.us.com/ https://www.retrosairjordan.us/ https://www.nikeoutletstoresonlineshopping.us.com/ https://www.goldensgoose.us.com/ https://www.fitflop-shoes.us.org/ https://www.jordansshoesforsale.us.com/ https://www.jordan12retro.us.com/ https://www.airjordan3s.us/ https://www.jordan13s.us/ https://www.retro-jordans.us/ http://www.pandorarings.us.com/ https://www.jordan-4.us.com/ https://www.jordan11red.us.com/ https://www.valentinosshoes.us.org/ https://www.airjordanshoess.us.com/ https://www.eccos.us.com/ https://www.lebron-shoes.us.com/ https://www.nike--shoes.us.com/ https://www.christianslouboutin.uk.com/ https://www.yeezyonline.us.com/ https://www.air-jordanssneakers.us/ https://www.shoeslouboutin.us.com/ https://www.mensnikeshoes.us.com/ https://www.nikeofficialwebsite.us.com/ https://www.airmax270.us.org/ https://www.pandoracanadajewelry.ca/ https://www.jordansneakerss.us/ https://www.jordan11low.us.com/ https://www.pandoras.us.com/ https://www.nikesfactory.us.com/ https://www.pandorajewelryofficialsite.us.com/ https://www.adidasyeezysshoes.us.com/ https://www.outletnikestore.us.com/ https://www.airjordansneakers.us.com/ https://www.new-jordans.us.com/ https://www.jordan10.us.com/ https://www.jordans5.us/ https://www.air-jordan4.us.com/ https://www.nmds.us.com/

コメントを入力. Wiki文法が有効です:
 
ratchet/0.4/push.txt · 最終更新: 2020/12/01 17:32 by y2sunlight