#php #sockets #client-server
#php #сокеты #клиент-сервер
Вопрос:
Моя страница php содержит соединение с TCP-сервером, которое будет получать баллы с моего GPS-устройства, которое будет отправлять данные каждые 30 секунд.
У меня есть несколько устройств (на данный момент 10Nos), и я получаю данные в течение некоторого времени, и внезапно они перестают получать данные. Он случайным образом останавливается через несколько минут (иногда он работает в течение 20 минут, а иногда и в течение 90 минут), но на самом деле он должен работать вечно.
Когда я писал с помощью лог -файлов, казалось, что он всегда застревает на socket_read()
.
Я также пробовал с помощью set_select неблокирующие коды и коды тайм-аута.
<?php
#!/usr/bin/env php
#!/usr/local/bin/php –q
# server.php
// don't timeout!
set_time_limit(0);
$host = "198.100.260.123";//example;
$port = 1812;
$db_conx = mysqli_connect("localhost","trackcps",'ajbbdjsjdPsM!1=',"jshahsH");
if(mysqli_connect_errno()){
exit();
}
$str1=$strls=$strlons=$input="initial";
$string1="";
while(true)
{
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo socket_strerror(socket_last_error($socket));
exit;
}
// bind socket to port
$result = socket_bind($socket, $host, $port) ;
$result = socket_listen($socket, 3);
// spawn another socket to handle communication
$spawn = socket_accept($socket);
$numBytes = 100;
$numRead = 0;
while ($numRead < $numBytes)
{
$input = socket_read($spawn,$numBytes - $numRead);/// i tried PHP_read_normal and timeout
if ($input === false)
{
$error = socket_last_error();
socket_close($socket);
$socket = null;;
throw new Exception('Read error ('.$error.')');
exit(1)
//
}
$input = trim($input);
$numRead = strlen($input);
$string1.= $input;
}
//////////////FORMATING AND INSERTING DATA INTO DATABASE
$str1=$strls=$strlons="empty";
if(!empty($str1) amp;amp; !empty($strls) amp;amp; !empty($strlons)amp;amp; !empty($gdtme)amp;amp; !empty($strspd)amp;amp; !empty($strang)amp;amp;
!empty($strdst)){
$sqlg = "INSERT IGNORE INTO devicedata1
(Deviceid,Latitude,Longitude,Recordedtime,Speed,Angle,main_power,ignition_status,remning_code,Distance,gps_code)
VALUE
('$str1','$strls','$strlons','$gdtme','$strspd','$strang','$strdevpow','$strignsts','$strunkncd','$strdst','$inpu
t')";
mysqli_query($db_conx,$sqlg);
}
socket_close($spawn);
socket_close($socket);
//echo $string1;
}
mysqli_close($db_conx);
socket_close($socket);
?>
пожалуйста, обратитесь к моему фактическому коду, который содержит файлы журнала n, и ни один из них не сообщается error….it работал нормально, и несколько раз он случайным образом останавливается на socket_read() … после записи сообщения журнала «выше начала чтения файла»….
#!/usr/bin/env php
<?php
# server.php
$host = "198.57.348.3";//198.57.208.222";
//echo "iam in server";
$port = 1812;
// don't timeout!
set_time_limit(0);
$file1 = 'g4log1.txt';
$db_conx = mysqli_connect("localhost","eetrackc_gps",'vEewwtPsM!1=',"rwerackc_gpsdata");
if(mysqli_connect_errno()){
exit();
}
$cnt =1;
$str1=$strls=$strlons=$input="initial";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!is_resource($socket)) {
// echo 'Unable to create socket: '. socket_strerror(socket_last_error()) . PHP_EOL;
}
if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
//echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL;
}
if (!socket_bind($socket, $host, $port) ) {
// echo 'Unable to bind socket: '. socket_strerror(socket_last_error()) . PHP_EOL;
exit(1);
}
$rval = socket_get_option($socket, SOL_SOCKET, SO_REUSEADDR);
if ($rval === false) {
echo 'Unable to get socket option: '. socket_strerror(socket_last_error()) . PHP_EOL;
} else if ($rval !== 0) {
echo 'SO_REUSEADDR is set on socket !' . PHP_EOL;
}
///////////////////////////////////
// bind socket to port
//$result =
$isrunning= true;
$tempflag= true;
// start listening for connections
$result = socket_listen($socket,1);
$string1="";
socket_set_nonblock($socket);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 0, "usec" => 50000));
while(1)
{
try
{
$spawn= socket_accept($socket);
if($spawn!== false amp;amp; $spawn > 0 )
{
error_log("n above start of read file",3,$file1);
if(($input = socket_read($spawn, 100))!== false)
{
error_log("n start in read file",3,$file1);
$tempflag=true;
$str1=$strls=$strlons="empty";
$string1 = $string1.$input;
//////////////formating buffer to keep in database//////////////
////////
error_log("n before inserting to database in read file",3,$file1);
if(!empty($str1) amp;amp; !empty($strls) amp;amp; !empty($strlons)amp;amp; !empty($gdtme)amp;amp; !empty($strspd)amp;amp;
!empty($strang)amp;amp; !empty($strdst))
{
$sqlg = "INSERT IGNORE INTO device_data
(Deviceid,Latitude,Longitude,Recordedtime,Speed,Angle,main_power,ignition_status,remning_code,Distan
ce,gps_code) VALUE
('$str1','$strls','$strlons','$gdtme','$strspd','$strang','$strdevpow','$strignsts','$strunkncd','$s
trdst','$input')";
if(false == mysqli_query($db_conx,$sqlg))
{
error_log("aravind killing page5 n",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
socket_shutdown($socket);
socket_close($socket);
mysqli_close($db_conx);
die();
}
}
error_log("n last end in read file",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
}else if($input=="")
{ error_log("aravind killing page read failed123 n",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
socket_shutdown($socket);
socket_close($socket);
mysqli_close($db_conx);
exit(1);
}else
{ //read failed...
//$cnt =1;
error_log("aravind killing page read failed n",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
socket_shutdown($socket);
socket_close($socket);
mysqli_close($db_conx);
exit(1);
}
}//spawn false
else
if($spawn <0)
{
$isrunning= true;
error_log("aravind killing page3 n",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
socket_shutdown($socket);
socket_close($socket);
mysqli_close($db_conx);
die();
}else
{
if($tempflag)
{
$tempflag= false;
date_default_timezone_set('Asia/Kolkata');
$curruntme = date("Y-m-d H:i:s");
$date12 = new DateTime($curruntme);
$date12->sub(new DateInterval('P0Y0M0DT0H0M0S'));
$Prevtime = $date12->format('Y-m-d H:i:s');
error_log( "nara",3,$file1);
error_log( $Prevtime . " curr = ".$curruntme ,3,$file1);
}else
{
// error_log( "nculprit not firing",3,$file1);
}
// error_log( $Prevtime . " curr = ".$curruntme ,3,$file1);
$curruntme = date("Y-m-d H:i:s");
$date12 = new DateTime($curruntme);
$date12->sub(new DateInterval('P0Y0M0DT0H3M0S'));
$curruntme = $date12->format('Y-m-d H:i:s');
if($Prevtime < $curruntme)
{
error_log($curruntme,3,$file1);
error_log("aravind killing page n" ,3,$file1);
error_log( $Prevtime,3,$file1);
$isrunning= false;
}
if(!$isrunning)
{
$isrunning= true;
error_log("aravind killing page2 n",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
socket_shutdown($socket);
socket_close($socket);
mysqli_close($db_conx);
die();
}
}
//echo $string1;
} catch(exception $e1)
{
error_log("aravind killing page4 n",3,$file1);
socket_close($socket);
mysqli_close($db_conx);
exit(1);
}
//at the end of loop checking if it iterates more then 3 min time and killing the process
$curruntme = date("Y-m-d H:i:s");
$date12 = new DateTime($curruntme);
$date12->sub(new DateInterval('P0Y0M0DT0H3M0S'));
$curruntme = $date12->format('Y-m-d H:i:s');
if($Prevtime < $curruntme)
{
error_log($curruntme,3,$file1);
error_log("aravind killing page at end of whilen" ,3,$file1);
error_log( $Prevtime,3,$file1);
$isrunning= false;
}
if(!$isrunning)
{
$isrunning= true;
error_log("aravind killing page2 at end of whilen",3,$file1);
socket_shutdown($spawn);
socket_close($spawn);
socket_shutdown($socket);
socket_close($socket);
mysqli_close($db_conx);
die();
}
}
socket_close($socket);
mysqli_close($db_conx);
?>
Комментарии:
1. Попробуйте настроить пользовательский обработчик ошибок и таким образом перехватывать все предупреждения или ошибки, которые
socket_read()
возникают. Изучите их и добавьте больше деталей в этот вопрос, пожалуйста. В противном случае это чистая догадка.2. спасибо за повтор Linus Kleen …. пожалуйста, найдите мой код с записанными журналами, и даже я попробовал с пользовательским обработчиком ошибок… но не получил желаемого результата…