開発プロセスでは、次のような状況に遭遇することがよくあります。フロントエンドのリストにはバックエンドのデータベースのデータが表示されますが、バックエンドの特定のインターフェースでデータベースにデータが挿入されるとデータベースは更新されますが、フロントエンドの表示データは更新されません。更新されていないため、手動で更新する必要があります。しかし、毎回手動でアップデートするのは面倒なので、Workermanを利用することで問題を解決できます。
Workerman Framework は、純粋に PHP で開発されたオープンソースの高性能 PHP ソケット サーバー フレームワークです。モバイル アプリ、モバイル通信、WeChat アプレット、モバイル ゲーム サーバー、オンライン ゲーム、PHP チャット ルーム、ハードウェア通信、スマート ホーム、車両のインターネット、モノのインターネット、その他の分野の開発で広く使用されています。 TCP の長い接続をサポートし、Websocket、HTTP およびその他のプロトコルをサポートし、カスタム プロトコルをサポートします。非同期 Mysql、非同期 Redis、非同期 Http、非同期メッセージ キューなど、多くの高性能コンポーネントを備えています。
では、上記の問題を解決するには、どのように使用すればよいでしょうか?
1. フロント エンドとバック エンドは、メッセージを相互にプッシュするための長い WebSocket 接続を確立します。
2. バック エンド内でリッスン プロセスが確立されます (プロトコル制限なし)
3. インターフェイスがデータベースにデータを正常に挿入した後、データは内部リスニング ポート
4. 内部リスニング ポートからプッシュ メッセージを受信した後、データがプッシュされます。ポートに接続すると、バックエンドがフロントエンドにデータをプッシュします。WebSocket を介してメッセージをプッシュして、リフレッシュを実現します。
workman フレームワークのソース コードをダウンロードしたら、上記のプロセスを実装しましょう。
実装コード:
server.php
<?php use Workerman\Worker; require_once __DIR__ . '/../../vendor/autoload.php'; // 初始化一个worker容器,监听1234端口 $worker = new Worker('websocket://0.0.0.0:1234');// /* * 注意这里进程数必须设置为1,否则会报端口占用错误 * (php 7可以设置进程数大于1,前提是$inner_text_worker->reusePort=true) */ $worker->count = 1; // worker进程启动后创建一个text Worker以便打开一个内部通讯端口 $worker->onWorkerStart = function($worker) { // 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符 $inner_text_worker = new Worker('text://0.0.0.0:5678'); $inner_text_worker->onMessage = function($connection, $buffer) { // $data数组格式,里面有uid,表示向那个uid的页面推送数据 $data = json_decode($buffer, true); $uid = $data['uid']; // 通过workerman,向uid的页面推送数据 $ret = sendMessageByUid($uid, $buffer); // 返回推送结果 $connection->send($ret ? 'ok' : 'fail'); }; // ## 执行监听 ## $inner_text_worker->listen(); }; // 新增加一个属性,用来保存uid到connection的映射 $worker->uidConnections = array(); // 当有客户端发来消息时执行的回调函数 $worker->onMessage = function($connection, $data) { global $worker; // 判断当前客户端是否已经验证,既是否设置了uid if(!isset($connection->uid)) { // 没验证的话把第一个包当做uid(这里为了方便演示,没做真正的验证) $connection->uid = $data; /* 保存uid到connection的映射,这样可以方便的通过uid查找connection, * 实现针对特定uid推送数据 */ $worker->uidConnections[$connection->uid] = $connection; return; } }; // 当有客户端连接断开时 $worker->onClose = function($connection) { global $worker; if(isset($connection->uid)) { // 连接断开时删除映射 unset($worker->uidConnections[$connection->uid]); } }; // 向所有验证的用户推送数据 function broadcast($message) { global $worker; foreach($worker->uidConnections as $connection) { $connection->send($message); } } // 针对uid推送数据 function sendMessageByUid($uid, $message) { global $worker; if(isset($worker->uidConnections[$uid])) { $connection = $worker->uidConnections[$uid]; $connection->send($message); return true; } return false; } // 运行所有的worker Worker::runAll();
push.php
<?php //插入数据库操作 // 建立socket连接到内部推送端口 $client = stream_socket_client('tcp://127.0.0.1:5678', $errno, $errmsg, 1); // 推送的数据,包含uid字段,表示是给这个uid推送 $data = array('uid'=>'uid1', 'percent'=>'88%'); // 发送数据,注意5678端口是Text协议的端口,Text协议需要在数据末尾加上换行符 fwrite($client, json_encode($data)."\n"); // 读取推送结果 echo fread($client, 8192); ?>
clien.html
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <script> var ws = new WebSocket('ws://127.0.0.1:1234'); ws.onopen = function(){ var uid = 'uid1'; ws.send(uid); }; ws.onmessage = function(e){ //alert(e.data); console.log(e.data); //window.location.reload(); }; </script> </body> </html>
実行プロセス:
cmd を開いて、server.php を実行します。
フロントエンド ページとコンソールを開きます
#cmd を開いて、push.php## を実行します。
#この時点で、フロントエンド ページの表示中に、コンソールがメッセージを受信しました。ワーカーマンの詳細については、PHP 中国語 Web サイトの
ワーカーマン チュートリアル以上がWorkerman のフロントエンドにバックエンド メッセージをリアルタイムでプッシュする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。