我正在努力让我的PHP服务器更有效率。
我已经构建了一个名为Client
的对象,它包含连接的客户端(与服务器有一个开放的套接字连接)信息,例如name
,id
等。
现在我有一个套接字连接数组和一个Client对象数组。 当我引用连接时,我在我的Client数组中搜索以找到匹配此连接的正确客户端。 它工作得很好,但是效率有点低......对于服务器中的少量客户端你感觉不到,但我担心如果我有数千个连接,它会减慢服务器速度。
作为一个解决方案,我想到了二维数组,但我在设计它时存在逻辑问题。
我可以这样做:
$clients = array();
$temp = array($newsock, new Client());
$clients[] = $temp;
我希望我的$clients[]
成为套接字而$clients[][]
成为客户端对象。
在$client
的每一行中,我只有$client[$index][0]
,它将成为该连接的客户端对象。
我可以将其发送到socket_select()
功能吗?
答案 0 :(得分:1)
您说您的客户端对象中有id
属性。为什么不使用id
作为两个数组的键?
您甚至可以将连接和客户端对象保存在一个数组中,每个数组都位于我之前讨论过的同一个键下的一个对象中 - 客户端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
如果您选择开始分叉流程,也许可能对您有帮助。