我正在尝试创建一个PHP脚本,它执行以下操作:
这就是它的样子(我只复制部分脚本,因为它跨越多个类,并且很难复制每个部分):
脚本中主要对象的构造
//connecting to the designated port for communication
$this->nodeServer = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($this->nodeServer, SOL_SOCKET, SO_REUSEADDR, 1);
if (socket_connect($this->nodeServer,"xxx.xxx.xxx.xxx",'14000') === false) {
throw new UnexpectedValueException("Failed to connect: " . socket_strerror(socket_late_error()));
exit;
}
//starting to listen on the designated port
$this->socketListener = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($this->socketListener, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($this->socketListener, 0, $this->listeningPort);
socket_listen($this->socketListener);
//adding these two sockets(the connected one, and the listener one) to an array
$this->addSocket($this->nodeServer);
$this->addSocket($this->socketListener);
在主文件中,我执行以下操作:
主要文件
$connectedToNode=true;
while ($connectedToNode) {
//manage multipal connections
$changedRead = $PHPWorker->socketList;
$changedWrite = $PHPWorker->socketList;
socket_select($changedRead, $changedWrite, $null, 0, 10);
echo 'This is a test echo'; // ECHO NR. 1
//check for new socket
if (in_array($PHPWorker->socketListener, $changedRead)) {
$socket_new = socket_accept($PHPWorker->socketListener); //accpet new socket
$PHPWorker->addSocket($socket_new); //add socket to client array
$header = socket_read($socket_new, 1024); //read data sent by the socket
socket_getpeername($socket_new, $ip); //get ip address of connected socket
echo "Someone connected"; // ECHO NR. 2
echo $ip; // ECHO NR. 3
//make room for new socket
$found_socket = array_search($PHPWorker->socketListener, $changedRead);
unset($changedRead[$found_socket]);
}
foreach ($changedRead as $changed_socket) {
//if I get an incomming message, process it
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
echo "This is the second test"; // ECHO NR. 4
$socketid = array_search($changed_socket, $PHPWorker->socketList);
$PHPWorker->processMessage($socketid, $buf);
}
$buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);
if ($buf === false) { // check disconnected client
// remove client for array
$socketid = array_search($changed_socket, $PHPWorker->socketList);
if (($socketid==0) || ($socketid==1)) {
//the first element is the "nodeServer", the second element is the listener, if either one goes away, stop the script
$connectedToNode=false;
}
//unset the disconnected client
unset($PHPWorker->socketList[$socketid]);
unset($PHPWorker->socketData[$socketid]);
}
}
}
我目前设法连接到" NodeServer",我能够与它通信,它工作得很好,但我无法设法从另一个PHP脚本连接到这个PHP脚本的监听器。
这是我尝试的方式(来自另一个对象的另一部分):
$this->PHPHelper = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($this->PHPHelper, SOL_SOCKET, SO_REUSEADDR, 1);
$hostip=gethostbyname('myhost.name.here');
if (!socket_connect($this->PHPHelper, $hostip, $portOnWhichMainSocketIsListening)) {
echo socket_strerror(socket_last_error());
socket_clear_error();
$this->PHPHelper=null;
} else {
socket_send($this->PHPHelper, "test\0", strlen("test\0"), 0);
}
while循环中的回声是用于测试的,奇怪的是,echo nr 1只被触发一次,nr.2和nr.3永远不会被触发,每次发送消息时都会触发nr.4从NodeServer到监听器php脚本。
可能是什么问题?我究竟做错了什么?不应该在每个循环中发生第一次回声吗?
此脚本的部分内容来自此页面的灵感:http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html
修改 好吧,似乎我找到了一个解决方案,但我仍然不明白为什么会这样做:
在以下代码的 while 部分:
foreach ($changedRead as $changed_socket) {
//if I get an incomming message, process it
while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)
{
echo "This is the second test"; // ECHO NR. 4
...
}
}
我已经插入了break 2;
命令,该命令返回主循环的权限,以继续执行。这样,我可以从其他PHP文件连接到侦听器套接字,并且回声也会触发。但我的问题是,为什么在没有break
命令的情况下,执行会停留在内部而和 周期内?