長い接続とは何ですか?
友達は多くのオンラインチャットツールやWebオンラインチャットツールを見たことがあるはずです。学校では、誰かがあなたに返信すると、この時点でページを更新していない場合に、メールボックスにメッセージが表示されます。 Web ページが一度も更新されていない場合でも、Web サイトはすぐに通知します。そういえば、継続的なデータ対話のためにリンクを再利用するということは、誰もがよく知っているはずです。現在、多くのインターネット ビジネス シナリオでは、ゲーム、チャット、情報プッシュなど、長時間接続のサポートが必要です。そのため、多くの同様の機能が長時間接続から切り離せません。前の章ではphpソケット通信を紹介しましたが、この章ではphpソケットのロング接続について紹介します。
長い接続と短いリンク
短い接続は通常、サーバーがクライアントにデータを積極的に「プッシュ」することはできませんが、長い接続を使用するとはるかに優れています。 - エンドおよびフロントエンド テクノロジーは、サーバーの「情報のプッシュ」機能を実現でき、データベースに更新がある場合、バックエンド プログラムは繰り返し要求する代わりに、データを即座に「プッシュ」できます。何度も接続と切断を繰り返します。
おそらく次のような説明があります:
いわゆる長い接続とは、SOCKET 接続が使用されているかどうかに関係なく接続されたままであることを意味しますが、いわゆる短い接続は、接続後のセキュリティが低いことを意味します。 SOCKET 接続が確立され、データが送受信されます。通常、銀行では、データが送信中か受信中かに関係なく、短い接続が使用されます。ショートコネクションとは、データ送信時のみコネクションを確立し、クライアント・サーバー間の通信・データ送信が完了するとコネクションを閉じることを意味します。
通信方法
各ネットワーク要素間には、ロング接続とショート接続の 2 つの接続方法があります。いわゆるロングコネクションとは、TCP 接続を維持している間、データ パケットが送信されない場合、接続を維持するために双方が検出パケットを送信する必要があることを意味します。短い接続とは、通信する当事者がデータ交換を行うときに、データの送信後に TCP 接続が確立されること、つまり、各 TCP 接続が 1 組の CMPP メッセージの送信を完了するだけであることを意味します。
短い接続: たとえば、HTTP は接続、リクエスト、および終了のみを行い、サーバーが一定時間内にリクエストを受信しない場合、接続を閉じることができます。長時間接続: CMPP など、一部のサービスはサーバーに長時間接続する必要があり、通常はサービス自体をオンラインに維持する必要があります。
PHP スクリプトにアクセスするたびに、すべての PHP スクリプトが実行された後でのみ戻り結果を取得します。スクリプトを継続的に実行する必要がある場合は、操作の目的を達成するために PHP の長い接続を使用する必要があります。
長い接続でプレイしたい場合は、ソケットのカプセル化を処理する必要があります。以下は、長いソケット接続を実行するコードです。サンプルコードは次のとおりです:
<?php $sfd = socket_create(AF_INET, SOCK_STREAM, 0); socket_bind($sfd, "0.0.0.0", 1234); socket_listen($sfd, 511); socket_set_option($sfd, SOL_SOCKET, SO_REUSEADDR, 1); socket_set_nonblock($sfd); $rfds = array($sfd); $wfds = array(); do{ $rs = $rfds; $ws = $wfds; $es = array(); $ret = socket_select($rs, $ws, $es, 3); //读取事件 foreach($rs as $fd){ if($fd == $sfd){ $cfd = socket_accept($sfd); socket_set_nonblock($cfd); $rfds[] = $cfd; echo "new client coming, fd=$cfd\n"; }else{ $msg = socket_read($fd, 1024); if($msg <= 0){ //close }else{ echo "on message, fd=$fd data=$msg\n"; } } } //写入事件 foreach($ws as $fd){ socket_write($fd, ........); } }while(true); ?>
効率を改善してみましょう:
<?php $sfd = stream_socket_server ('tcp://0.0.0.0:1234', $errno, $errstr); stream_set_blocking($sfd, 0); $base = event_base_new(); $event = event_new(); event_set($event, $sfd, EV_READ | EV_PERSIST, 'ev_accept', $base); event_base_set($event, $base); event_add($event); event_base_loop($base); function ev_accept($socket, $flag, $base) { $connection = stream_socket_accept($socket); stream_set_blocking($connection, 0); $buffer = event_buffer_new($connection, 'ev_read', NULL, 'ev_error', $connection); event_buffer_base_set($buffer, $base); event_buffer_timeout_set($buffer, 30, 30); event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff); event_buffer_priority_set($buffer, 10); event_buffer_enable($buffer, EV_READ | EV_PERSIST); } function ev_error($buffer, $error, $connection) { event_buffer_disable($buffer, EV_READ | EV_WRITE); event_buffer_free($buffer); fclose($connection); } function ev_read($buffer, $connection) { $read = event_buffer_read($buffer, 256); //do something.... } ?>
人数の増加と同時実行性の向上により、単一のプロセスでは需要を満たすことができなくなり、この問題を解決するには、swoole、workerman などの既製の拡張機能とライブラリがありますか?しかし、PHP を使用して Web 開発を行う場合、Web サーバー関連のライブラリを開発に使用することはありませんよね。単純なエコーを実行するだけです。こういった複雑なことはすべてnginxやapacheに引き継がれ、躊躇することなく前面に出てくるので、私たちはロジックを書くことに集中できます。ソケット サービスの作成は、Web サービスの作成と同じように高度なものではありません。それらはすべてコーディングして要件を完了するものですが、1 つは nginx によって完了し、もう 1 つは自分で完了します。 。ただし、nginx+fpm、fooking+fpm=php のような長い接続のソリューションでは、接続の伝送にゲートウェイが使用され、メッセージの転送にルーターが使用されます。
コードは次のとおりです:<?php $sid = $_SERVER['SESSIONID'];//这是sessionid $data = file_get_contents("php://input");//这样就能拿到请求内容了 //想要返回消息只需要两步 header('Content-Length: 11');//返回给客户端字节数 echo "hello world"; //想要给别的用户发消息 include 'api.php'; $router = new RouterClient('router host', 'router port'); $router->sendMsg(用户sessionid, "fuck you"); //想要给所有人要消息 $router->sendAllMsg("fuck all"); //想给指定组发消息(类似redis的pub/sub) $router->publish("channel name", "fuck all"); ?>
【おすすめ関連チュートリアル】1.「
php.cn Dugu Jiijian (4) - PHPビデオチュートリアル」
2. phpプログラミング入門から上級までチュートリアルのセット
以上がPHPソケットで長い接続を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。