次のコラム workerman チュートリアルでは、workerman に基づいてリアルタイム プッシュを実装し、Ajax ポーリングを放棄する方法を紹介します。
最初にこれらのことについて話しましょう:
TCP/IP
TCP/IP はプロトコル グループです。 . ネットワーク層、トランスポート層、アプリケーション層の3層に分かれています。
ネットワーク層には、IP プロトコル、ICMP プロトコル、ARP プロトコル、RARP プロトコル、および BOOTP プロトコルがあります。
トランスポート層にはTCPプロトコルとUDPプロトコルがあります。
アプリケーション層には次のものがあります。
TCP には FTP、HTTP、TELNET、SMTP などのプロトコルが含まれます。
UDP には DNS、TFTP などが含まれます。プロトコル
短い接続
接続->データ転送->接続を閉じる
HTTP はステートレスです。ブラウザとサーバーが実行するたびに、 HTTP 操作。接続は一度確立されますが、タスクが完了すると接続は終了します。
また、「短い接続」とは、SOCKET 接続が送信され、データが受信された後、すぐに切断されることを意味するとも言えます。
長い接続
接続 ->データ転送 ->接続を維持 ->データ転送 ->。 。 。 -> 接続を閉じます。
長時間接続とは、SOCKET 接続が確立されているかどうかに関係なく接続を維持することを指しますが、セキュリティは貧弱です。
Http 長い接続
HTTP は長い接続を確立することもできます。Connection:keep-alive を使用します。HTTP 1.1 のデフォルトは永続的な接続です。 HTTP1.1とHTTP1.0を比較すると、最大の違いは永続接続サポートの追加(最新のhttp1.0ではキープアライブを明示的に指定できるようです)ですが、やはりステートレスというか信頼できません。
長い接続と短い接続をいつ使用するか?
長い接続は主に頻繁な操作やポイントツーポイント通信に使用され、接続数が多すぎることはできません。各 TCP 接続には 3 段階のハンドシェイクが必要であり、時間がかかります。各操作を接続してから操作すると、処理速度が大幅に低下します。そのため、各操作後に切断されず、途中でデータ パケットが直接送信されます。最初の処理です。TCP 接続を確立する必要はありません。例: データベース接続には長い接続が使用されますが、短い接続で頻繁に通信するとソケット エラーが発生し、頻繁にソケットを作成するとリソースの無駄になります。
WEB Web サイトのような HTTP サービスでは、長い接続はサーバーの特定のリソースを消費するため、通常、短いリンクが使用され、WEB Web サイトでは数千のリンクが頻繁に使用されます。クライアント接続では、短い接続を使用するとリソースが節約されますが、長い接続が使用され、同時に数千のユーザーがいる場合は、各ユーザーが 1 つの接続を占有することが考えられます。したがって、同時実行量は多くなりますが、頻繁な操作が必要ない場合、各ユーザーは短い接続を使用する必要があります。
ワーカーマンそれは何ですか? Workerman は、純粋に PHP で開発されたオープンソースの高性能 PHP ソケット サーバー フレームワークです。モバイル アプリ、モバイル通信、WeChat アプレット、モバイル ゲーム サーバー、オンライン ゲーム、PHP チャット ルーム、ハードウェア通信、スマート ホーム、車両のインターネット、モノのインターネット、その他の分野の開発で広く使用されています。 TCP の長い接続をサポートし、Websocket、HTTP およびその他のプロトコルをサポートし、カスタム プロトコルをサポートします。非同期 Mysql、非同期 Redis、非同期 Http、非同期メッセージ キューなど、多くの高性能コンポーネントを備えています。
本題に移りましょう: リアルタイム通信を実現するために、図に示すように、多くの場合、ajax ポーリング メカニズムが使用されます。 Workerman メソッドは後で使用できます。実装、プロジェクトも TP によって書かれています。公式マニュアルには、上の図に示すように、
は他の mvc フレームワークと組み合わせることが推奨されています (例として ThinkPHP) :
1. ThinkPHP と Workerman は 2 つ独立しています システムは、相互に干渉することなく独立して展開されます (異なるサーバーに展開できます)。 2. ThinkPHP は HTTP プロトコルを使用して、ブラウザーでレンダリングおよび表示するための Web ページを提供します。 3. ThinkPHP によって提供されるページの js は、WebSocket 接続を開始し、ワーカーマンに接続します4. 接続後、データ パケット (ユーザー名、パスワード、または何らかのトークンを含む) string) は検証のためにワーカーマンに送信され、WebSocket 接続がどのユーザーに属しているかがわかります。 5. ThinkPHP がブラウザーにデータをプッシュする必要がある場合にのみ、ワーカーマンのソケット インターフェースを呼び出してデータをプッシュします。 6. 残りのリクエストは、ThinkPHP の元の HTTP メソッドに従って処理されます。概要:
Workerman をブラウザにプッシュできるチャネルとして使用し、データをプッシュする必要がある場合にのみ Workerman インターフェイスを呼び出してプッシュを完了します。ブラウザ。ビジネスロジックはすべてThinkPHP内で完結します。わかりました、ここで、workerman コンテナを実行します。これは CLI モードで実行されていることに注意してください。
次に、次のように情報の受信で再生します。添付コード
<script> // 连接服务端 var socket = io('http://127.0.0.1:2120'); // uid可以是自己网站的用户id,以便针对uid推送 uid = 123; // socket连接后以uid登录 socket.on('connect', function(){ socket.emit('login', uid); }); // 后端推送来消息时 socket.on('new_msg', function(msg){ console.log("收到消息:"+msg); //自己业务逻辑处理 }); </script>
次に、ユーザーがユーザーに情報を送信するときに
// 指明给谁推送,为空表示向所有在线用户推送 $to_uid = "123"; // 推送的url地址 $push_api_url = "http://127.0.0.1:2121/"; $post_data = array( "type" => "publish", "content" => "数据", "to" => $to_uid, ); $ch = curl_init (); curl_setopt ( $ch, CURLOPT_URL, $push_api_url ); curl_setopt ( $ch, CURLOPT_POST, 1 ); curl_setopt ( $ch, CURLOPT_HEADER, 0 ); curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data ); curl_setopt ($ch, CURLOPT_HTTPHEADER, array("Expect:")); $return = curl_exec ( $ch ); curl_close ( $ch ); var_export($return);
を追加します。このうち、workerman のプッシュ コア コードに
// 全局数组保存uid在线数据 $uidConnectionMap = array(); // 记录最后一次广播的在线用户数 $last_online_count = 0; // PHPSocketIO服务 $sender_io = new SocketIO(2120); // 客户端发起连接事件时,设置连接socket的各种事件回调 // 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据 $sender_io->on('workerStart', function(){ // 监听一个http端口 $inner_http_worker = new Worker('http://0.0.0.0:2121'); // 当http客户端发来数据时触发 $inner_http_worker->onMessage = function($http_connection, $data){ global $uidConnectionMap; $_POST = $_POST ? $_POST : $_GET; // 推送数据的url格式 type=publish&to=uid&content=xxxx switch(@$_POST['type']){ case 'publish': global $sender_io; $to = @$_POST['to']; $_POST['content'] = htmlspecialchars(@$_POST['content']); // 有指定uid则向uid所在socket组发送数据 if($to){ $sender_io->to($to)->emit('new_msg', $_POST['content']); // 否则向所有uid推送数据 }else{ $sender_io->emit('new_msg', @$_POST['content']); } // http接口返回,如果用户离线socket返回fail if($to && !isset($uidConnectionMap[$to])){ return $http_connection->send('offline'); }else{ return $http_connection->send('ok'); } } return $http_connection->send('fail'); }; }); if(!defined('GLOBAL_START')) { Worker::runAll(); }
ok を実装すれば完了です。
以上がワーカーベースのリアルタイムプッシュ (Ajax ポーリングの放棄)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。