1

我正在尝试使我的 PHP 服务器更有效率。我构建了一个名为的对象Client,其中包含已连接的客户端(与服务器有一个开放的套接字连接)信息,例如nameid

现在我有一组套接字连接和一组客户端对象。当我提到一个连接时,我在我的客户端数组中搜索以找到与该连接匹配的正确客户端。它工作得很好,但效率有点低..对于服务器中的少量客户端你感觉不到,但我担心如果我有成千上万的连接它会减慢服务器的速度。

作为解决方案,我考虑了二维数组,但我在设计它时遇到了逻辑问题。

我可以做这样的事情:

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

我希望我$clients[]成为套接字和$clients[][]客户端对象。在每一行中,$client我将只有$client[$index][0]哪个将是我用于该连接的客户端对象。我可以将其发送到socket_select()函数吗?

4

1 回答 1

1

你说你在你的客户对象中有一个id属性。为什么不使用它id作为两个数组的键呢?

  • 套接字连接数组
  • 客户端对象数组

您甚至可以将连接和客户端对象保存在一个数组中,每个对象都在一个对象中,使用我之前谈到的相同键——客户端id

无论如何,无论您决定存储客户端连接对象,您都可以将其传递给所有相关的套接字函数 -

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

关于您的服务器的效率,我实现了一些分叉以将数据广播到大量客户端(所有客户端都在聊天服务器的示例中)。

这是我用于分叉广播的实现 -

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 回答