我正在尝试使用PHP套接字连接定期轮询服务器。但是,当我运行脚本时,我第一次得到正确的行为,但第二次我得到以下错误:
fsockopen(): php_network_getaddresses: getaddrinfo failed: Name or service not known
当我第三次运行脚本时,出现以下错误:
fsockopen(): unable to connect to :0 (Failed to parse address "")
该错误会在每次后续尝试中重复出现。 但是,如果我等待一分钟然后重试,那么一切正常。在我看来,我遇到套接字连接没有关闭的问题,然后当我再次尝试创建它时被拒绝。
处理套接字通信的类是:
class FsSocket
{
private $password = "XXXXXXXXXX";
private $port = "8030";
private $host = "hostname";
function event_socket_create( $host=null, $port=null, $password=null ) {
if ( $host == null ) {
$host = $this->host;
}
if ( $port == null ) {
$port = $this->port;
}
if ( $password == null ) {
$password = $this->password;
}
error_log( $host.":".$port );
$fp = fsockopen($host, $port, $errno, $errdesc, 2) or die("Connection to $host failed");
socket_set_blocking($fp,false);
if ($fp) {
while (!feof($fp)) {
$buffer = fgets($fp, 1024);
usleep(100); //allow time for reponse
if (trim($buffer) == "Content-Type: auth/request") {
fputs($fp, "auth $password\n\n");
break;
}
}
return $fp;
}
else {
return false;
}
}
function event_socket_request($fp, $cmd) {
if ($fp) {
fputs($fp, $cmd."\n\n");
usleep(100); //allow time for reponse
$response = "";
$i = 0;
$contentlength = 0;
while (!feof($fp)) {
$buffer = fgets($fp, 4096);
if ($contentlength > 0) {
$response .= $buffer;
}
if ($contentlength == 0) { //if contentlenght is already don't process again
if (strlen(trim($buffer)) > 0) { //run only if buffer has content
$temparray = explode(":", trim($buffer));
if ($temparray[0] == "Content-Length") {
$contentlength = trim($temparray[1]);
}
}
}
usleep(100); //allow time for reponse
//optional because of script timeout //don't let while loop become endless
if ($i > 10000) { break; }
if ($contentlength > 0) { //is contentlength set
//stop reading if all content has been read.
if (strlen($response) >= $contentlength) {
break;
}
}
$i++;
}
return $response;
}
else {
echo "no handle";
}
}
}
调用套接字类的代码如下:
$socket = new FsSocket();
$fp = $socket->event_socket_create();
$cmd = "sofia_contact $to->user@$to->domain";
$response = $socket->event_socket_request($fp, $cmd);
fclose($fp);
unset($socket);
我还没有实现循环位。我试图通过首先手动刷新页面来实现这一点。