2012-05-05 27 views
1

PHPサーバーをより効率的にしようとしています。 私はソケット接続の1つのアレイ、および1つのアレイを持っている今のところなどid2次元配列のsocket_select()

を、このようなnameとして接続されたクライアントが含まれていClient指定されたオブジェクト(サーバとのオープンソケット接続を持っている)情報を構築しましたクライアントオブジェクトの 私は接続を参照しているとき、私はこの接続に一致するクライアントを見つけるためにクライアント配列内を検索しています。 それは素晴らしいですが、それは少し非効率です。サーバのクライアントの少量のためにそれを感じることはありませんが、私は何千もの接続を持っているならそれはサーバーを減速させることを恐れています。

解決策として、私は約2次元配列を考えましたが、私はそれを設計するロジックの問題があります。

私はこのような何かを行うことができます。

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

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

答えて

1

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

  • ソケット接続配列
  • Clientオブジェクトの配列

あなたも、私が前の話と同じキーの下にあるオブジェクトにそれぞれ、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); 
} 

上記のコードは、私の以前の問題(すなわち、self answeredた)から持ち上げられました。
Terminating zombie child processes forked from socket server

おそらく、フォークプロセスの開始を選択した場合に役立つかもしれません。

+0

一般に、インデックスとしてidを使用すると、ソケット接続後にClientオブジェクトのidプロパティがクライアントによって送信される唯一の問題であり、サーバ。 pcntl_fork()関数についてもう少し説明できますか?私はUNIXに精通していないので、私はphp.netで読んだ説明を理解していませんでした。 –

+0

'pcntl_fork()'は** unixのようなシステム**でのみ動作します。パフォーマンスを向上させるために親プロセスとは別の子プロセスを作成するプロセスです。子プロセスは特定の要求を処理して、親サーバーが受信データの処理を続けることができます。 – Lix

+0

それは試してみると良いアイデアです...私の質問に戻って、あなたは何を提案していますか?配列(socket、new Client())をsocket_select()関数に送り返すことができますか?または多分私は(接続が行われた後にクライアントから受信される)一意のIDを待つ必要がありますし、ソケットにオブジェクトを接続するだけですか? –