socket_read() блокирует выполнение

#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 …. пожалуйста, найдите мой код с записанными журналами, и даже я попробовал с пользовательским обработчиком ошибок… но не получил желаемого результата…