ホームページ > ウェブフロントエンド > htmlチュートリアル > php+swooleを使用してクライアントデータをリアルタイムに更新する (2)_html/css_WEB-ITnose

php+swooleを使用してクライアントデータをリアルタイムに更新する (2)_html/css_WEB-ITnose

WBOY
リリース: 2016-06-21 09:00:27
オリジナル
1229 人が閲覧しました

前の記事では、swoole の基本的な使用方法について説明しました。ここでは、数行の基本的なステートメントを使用して、より複雑な論理演算を実装できます。

まず、ビジネス シナリオについて説明します。現在のアプリケーションのほとんどは、サーバー + インターフェイス + クライアントの形式で動作を調整します。この利点は、どの端末であってもサーバーと完全に互換性があることです。これにより、MVC のさまざまな部分の真の分離を簡単に実現できるようになります。ただし、プログラムの使いやすさを向上させるにはまだ長い道のりがあります。誰もが遭遇するであろう問題の 1 つは、リアルタイムのデータ更新の問題です。たとえば、ユーザーが携帯電話で追加操作を実行した場合、他の端末もデータの変更をタイムリーに表示する必要があります。携帯電話では、プッシュ アップデートを受信する際に、プッシュの内容に応じて対応するインターフェイスを要求するだけで、さまざまなプッシュ サービスがニーズに完全に対応できるため、これは比較的簡単に処理できます。しかし、PC ではそうではありません。ブラウザと http プロトコルの特殊な特性により、別の方法を見つける必要があります。

人生において誰もが遭遇するであろう場面を考えてみましょう。ある週末、ガールフレンドと映画に行きたいと思い、PC でショーの番号と座席を見つけました。注文して支払いをしようとしたとき、システムは座席が販売されたことを通知するメッセージを表示するため、座席選択ページに戻って新たに選択する必要があります。製品エクスペリエンスを改善すると、他のユーザーが特定の座席を購入すると、ブラウザーはその座席をすぐに販売済みとしてマークするため、何度も行き来する必要がなくなり、時間を節約できます。

** 上記のシナリオについて、システム間の対話のフローチャートを次に示します。 **

  • 上の行は、システムを使用している現在のユーザーです。 , 彼はデータに対して関連する操作を実行し、同時に操作結果を返しました

次の行は、他のユーザーも同じデータを操作していることを示しています。 ① (緑色) が結果を返すと、Web サーバーは現在のユーザーと Redis キュー サービス (① 黄色) に同時に通知します。これは、WebSocket サービスが Redis をリアルタイムで監視しているため、データが変更されると WebSocket がサービスはすぐにそれを感知します。このとき、ブラウザと確立した長時間の接続を介して通信し、データが更新されリロードされたことを通知します。

もう 1 つの方法は、① (緑) が結果を返すときに Redis キューに通知せず、データが変更されたことを WebSocket サービスと直接通信し、WebSocket サービスがブラウザ クライアントにリロードするように通知することです。この解決策は比較的単純であり、一部の操作をカプセル化するには swoole の方が便利であるため、ここではこのメソッドが使用されます

  • WebSocket 接続が開かれると、現在の登録 ID がソケット サービスに送信されます。このようにして、WebSocket サービスは指定された接続に直接データを送信できます。
ws.onopen = function(){    console.log("socket连接已打开");    $.post('/mercha/merchant/find',function(d){ //从web服务端获取注册id        d = $.parseJSON(d);        ws.send("merchantId_"+d.data.id);    })};
ログイン後にコピー
  • WebSocket サービスが登録 ID を受信すると、現在の接続 ID と照合されます。サーバーによって渡されたマーチャント ID。関係は redis
$server->on('Message', function ($serv, $frame) {    if(stripos($frame->data,'merchantId_') !== false){        $fd = $redis->get($frame->data);        if($fd != null){            $fd = json_decode($fd,true);        }        //这里的$frame->fd是指当前的websocket连接id,swoole会通过此id发送给对应的接收方,可以理解为手机号码        $fd[$frame->fd] = $frame->fd;        $fd = json_encode($fd);        $redis->set($frame->data,$fd);    }});
ログイン後にコピー
  • に書き込まれます。swoole_websocket_server は swoole_http_server から継承しているため、http
を介して WebSocket サービスと対話できます。
$server->on('Request', function ($req, $respone) {    if(isset($req->get['merchantId'])){        global $server;        global $redis;        $merchantId = $req->get['merchantId'];        $fd = $redis->get("merchantId_".$merchantId);        if($fd != null){            $fd = json_decode($fd,true);        }        $err = 0;        if(is_array($fd)){            foreach($fd as $f){                $res = @$server->push($f, "refresh");                if($res === false){                    unset($fd[$f]);                    $err++;                }            }            if($err){                $fd = json_encode($fd);                $redis->set("merchantId_".$merchantId,$fd);            }        }    }    $respone->end("success");});
ログイン後にコピー

* * 強調する必要があるのは、http リクエストを監視するサーバーにはプッシュ メソッドがないということです。そのため、ここでは websocket の $server を使用して、グローバル変数を通じてクライアントにデータを送信します**

上記は問題の解決策です。これは記事の最後に、WebSocket のサーバーのソース コードを添付します。多くのビジネスがあるため、統合します。実行するには、まず swoole 拡張機能をインストールする必要があります。インストール方法は以前の記事で説明していますので、参考までに説明します。

上記の Redis を使用する他の方法も非常に優れており、以前の Redis パブリッシュおよびサブスクライブ モデルの使用でも、基本的には目的の効果を達成できます。しかし、途中で問題が発生し、redis サブスクライブが数十秒間実行されると、RedisException がスローされます。その理由は、PHP の Redis ライブラリで使用されるサブスクライブは PHP の組み込みソケットを使用し、php.ini がデフォルトでソケット タイムアウトを 60 秒に設定するためです。そのため、default_socket_timeout 構成項目を見つけて、時間をより長い時間に変更するだけで済みます。 。または、ini_set('default_socket_timeout', -1);

WebSocket サーバーのソース コード

を追加します
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート