1

PHPサーバーをもう少し効率的にしようとしています。Client接続されたクライアント(サーバーとのオープンソケット接続がある)などの情報を含むというname名前のオブジェクトを作成しました。id

今のところ、ソケット接続の配列が1つと、クライアントオブジェクトの配列が1つあります。接続を参照しているときは、Client配列内を検索して、この接続に一致する適切なクライアントを見つけています。それはうまく機能しますが、少し非効率的です。サーバー内のクライアントの数が少ない場合、それを感じることはありませんが、何千もの接続があるとサーバーの速度が低下するのではないかと心配しています。

解決策として2次元配列を考えましたが、設計に論理的な問題があります。

私はこのようなことをすることができますか?

$clients = array();
$temp = array($newsock, new Client());
$clients[] = $temp;

私は自分$clients[]をソケットにし、$clients[][]をクライアントオブジェクトにしたい。の各行には、その接続のクライアントオブジェクトとなる$clientものだけがあります。これを関数$client[$index][0]に送信できますか?socket_select()

4

1 に答える 1

1

クライアントオブジェクト内に属性があると言いidます。idそれを両方のアレイのキーとして使用してみませんか?

  • ソケット接続アレイ
  • クライアントオブジェクト配列

接続とクライアントオブジェクトを1つの配列に保持し、それぞれを前に説明したのと同じキー(クライアント)の下にある1つのオブジェクトに保持できる場合もありますid

いずれにせよ、クライアント接続オブジェクトを格納することにした場合はいつでも、関連するすべてのソケット関数にそれを渡すことができます-

  • socket_select();
  • socket_accept();
  • socket_write();
  • 等...

サーバーの効率に関しては、大量のクライアント(チャットサーバーの例ではすべて)にデータをブロードキャストするためのフォークを実装しました。

これは、ブロードキャストをフォークするために使用した実装です-

function broadcastData($socketArray, $data){
        global $db;
        $pid = pcntl_fork();
        if($pid == -1) {
                // Something went wrong (handle errors here)
                // Log error, email the admin, pull emergency stop, etc...
                echo "Could not fork()!!";
        } elseif($pid == 0) {
                // This part is only executed in the child
                foreach($socketArray AS $socket) {
                        // There's more happening here but the essence is this
                        socket_write($socket,$msg,strlen($msg));
                        // TODO : Consider additional forking here for each client. 
                }
                // This is where the signal is fired
                exit(0);
        }
        // The child process is now occupying the same database 
        // connection as its parent (in my case mysql). We have to
        // reinitialize the parent's DB connection in order to continue using it. 
        $db = dbEngine::factory(_dbEngine); 
}

上記のコードは、私の前の質問から削除されました(それは自己回答でした)。
ソケットサーバーからフォークされたゾンビ子プロセスを終了する

おそらく、フォークプロセスを開始することを選択した場合に役立つ可能性があります。

于 2012-05-05T16:39:19.693 に答える