我使用SocketServer.class.php从GPS跟踪单元到我的服务器进行连接。发生什么事的一个简单例子。
单元连接到我的服务器,建立连接并将数据/缓冲区发送到服务器,并且设备断开连接,这告诉套接字关闭。但是在某些版本的设备上,设备不会关闭连接,插座保持打开状态,然后阻止连接和发送信息的其他设备的过程。我可以用什么PHP代码在幕后时间关闭连接/套接字或在一段时间后执行套接字超时?
因为这给我带来了两个问题。我可以拥有一个或另一个。 1)发送/接收第一批信息后关闭连接。但是单元有时发送的信息是在3缓冲区发送(希望我说的正确)所以现在我保持连接/套接字打开并等待单元说“我已经完成,关闭套接字”。这很好。但是,当该单元没有说“我已经完成”并且套接字保持打开但收到所有信息时,问题就出现了。 这是我的代码:
<?php
class SocketServer
{
protected $config;
protected $master_socket;
public $max_clients = 99999;
public $max_read = 32768;
public $clients;
public $complete_string = "";
public function __construct($bind_ip,$port)
{
set_time_limit(0);
$this->hooks = array();
$this->config["ip"] = $bind_ip;
$this->config["port"] = $port;
$this->master_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($this->master_socket,$this->config["ip"],$this->config["port"]) or die("Port ".$this->config["port"]." is still open\r\n");
socket_getsockname($this->master_socket,$bind_ip,$port);
socket_listen($this->master_socket);
SocketServer::debug("Listenting for connections on {$bind_ip}:{$port}");
}
public function loop_once()
{
// Setup Clients Listen Socket For Reading
$read[0] = $this->master_socket;
for($i = 1; $i <= $this->max_clients; $i++)
{
if(isset($this->clients[$i]))
{
$read[$i + 1] = $this->clients[$i]->socket;
}
}
// Set up a blocking call to socket_select
if(socket_select($read,$write = NULL, $except = NULL, $tv_sec = 8) < 1)
{
return true;
}
// Handle new Connections
if(in_array($this->master_socket, $read))
{
for($i = 1; $i <= $this->max_clients; $i++)
{
if(empty($this->clients[$i]))
{
$temp_sock = $this->master_socket;
$this->clients[$i] = new SocketServerClient($this->master_socket,$i);
SocketServer::debug("Client {$i} from {$this->clients[$i]->ip} connected @ ".date("d-M-Y H:i:s"), time());
break;
}
elseif($i == ($this->max_clients-1))
{
SocketServer::debug("Too many clients... :( ");
}
}
}
// Handle Input
for($i = 0; $i < $this->max_clients; $i++) // for each client
{
if(isset($this->clients[$i]))
{
if(in_array($this->clients[$i]->socket, $read))
{
$input = socket_read($this->clients[$i]->socket, $this->max_read);
if($input == null)
{
$this->disconnect($i);
}
else
{
$this->clients[$i]->complete_string .= $input;
}
}
}
}
return true;
}
public function disconnect($client_index,$message = "")
{
$i = $client_index;
SocketServer::debug("Lets interpret the string\r\n");
SocketServer::interpret();
SocketServer::debug("Client {$i} from {$this->clients[$i]->ip} disconnected");
SocketServer::debug("------------------------------------------------------------------------------------------------------------------------------------------");
$this->clients[$i]->destroy();
unset($this->clients[$i]);
}
public function interpret()
{
//Lets get the info to start
for($i = 0; $i < $this->max_clients; $i++) // for each client
{
if(isset($this->clients[$i]))
{
$complete_string = $this->clients[$i]->complete_string;
SocketServer::debug($complete_string);
//Do something with the string here
//Clear the Complete String Variable for next use
$this->clients[$i]->complete_string = "";
}
}
}
public function infinite_loop()
{
$test = true;
do
{
$test = $this->loop_once();
}
while($test);
}
public static function debug($text)
{
echo("{$text}\r\n");
}
function &__get($name)
{
return $this->{$name};
}
}
class SocketServerClient
{
protected $socket;
protected $ip;
protected $hostname;
protected $server_clients_index;
public function __construct(&$socket,$i)
{
$this->server_clients_index = $i;
$this->socket = socket_accept($socket) or die("Failed to Accept");
socket_getpeername($this->socket,$ip);
$this->ip = $ip;
}
public function lookup_hostname()
{
$this->hostname = gethostbyaddr($this->ip);
return $this->hostname;
}
public function destroy()
{
socket_close($this->socket);
}
function &__get($name)
{
return $this->{$name};
}
function __isset($name)
{
return isset($this->{$name});
}
}