1

我有多个 GPS 设备。我无法对此设备进行更改。它将数据发送到端口。

我打破这个传入的数据并根据其类型将其插入数据库。但有时我会遇到问题。设备有时会发送 id_number 字段为空白。它正确发送所有其他数据。有时程序会崩溃。

<?php
set_time_limit (0);
$ip_address = "xxx.xxx.xxx.xxx";
$port = "yyy";
$server = stream_socket_server("tcp://$ip_address:$port", $errno, $errorMessage);
if ($server === false) {
    die("stream_socket_server error: $errorMessage");
}
$client_sockets = array();
while (true) {
    // prepare readable sockets
    $read_sockets = $client_sockets;
    $read_sockets[] = $server;
    // start reading and use a large timeout
    if(!stream_select($read_sockets, $write, $except, 300000)) {
        die('stream_select error.');
    }
    // new client
    if(in_array($server, $read_sockets)) {
        $new_client = stream_socket_accept($server);
        if ($new_client) {
            //print remote client information, ip and port number
            //echo 'new connection: ' . stream_socket_get_name($new_client, true) . "\n";
            $client_sockets[] = $new_client;
            //echo "total clients: ". count($client_sockets) . "\n";
            // $output = "hello new client.\n";
            // fwrite($new_client, $output);
        }
        //delete the server socket from the read sockets
        unset($read_sockets[ array_search($server, $read_sockets) ]);
    }
    // message from existing client
    foreach ($read_sockets as $socket) {
        $data = fread($socket, 2048);
        echo "data: " . $data . "\n";
        if($data[0]=='$')        {
        write_file($data);
        $explp = array();
        $explp = explode("#",$data);
        $i=0;
        $j=count($explp);
        while ($i < ($j-1)){
          $listexa= explode(";",$explp[$i]);
          $location= explode(",",$listexa[0]); 
          $response = ""; 
          $id_number = $location[2];    
          $package_type = substr($location[0],1);
            if ($package_type == 'DATA')
            {
                $lati = substr($listexa[2],1);
                $longi = substr($listexa[3],2);
                $speed = $listexa[4];
                if(count($speed)>2)
                data_package($id_number,$package_no,'DATA');
            }
            else if($package_type=='GEOLOC')
            {
                $lati = substr($listexa[3],1);
                $longi = substr($listexa[4],2);
                $speed = $listexa[5];
                if($location[3]=='-' || $location[3]=='2' || $location[3]=='R')
                {   
                    $speed= '0';
                    $package_type = 'GEO';
                    geo_package($id_number,$package_no,$package_type);
                }
            }
            else if($package_type=='ALIVE')
            {
                alive_package($package_no,$id_number);
            }
          $i = $i+1;
                
            }
            if (!$data) {
                unset($client_sockets[ array_search($socket, $client_sockets) ]);
                @fclose($socket);
                //echo "client disconnected. total clients: ". count($client_sockets) . "\n";
                continue;
            }
            //send the message back to client
            if (sizeof($response) > 0) {
                fwrite($socket, $response);
            }
        }
} } 


function alive_package($package_no,$id_number){
    $link=dbcon();
    try{
    $statement = $link->prepare('INSERT INTO alive_packages (package_no, id_number)
    VALUES (:package_no, :id_number)');
    $statement->execute([
        'package_no' => $package_no,
        'id_number' => $id_number,
    ]);
    } 
    catch (PDOException $e) {
      echo "DataBase Error: The user could not be added.<br>".$e->getMessage(); write_file_log($e->getMessage());
      $link = null;
    } catch (Exception $e) {
      echo "General Error: The user could not be added.<br>".$e->getMessage(); write_file_log($e->getMessage());
      $link = null;
    }
        $link = null;
}
function data_package($id_number,$package_no,$package_type){
    $link=dbcon();
    $typee= '-';
    try{
    $statement = $link->prepare('INSERT INTO data_package (id_number, package_no, package_type)
    VALUES (:id_number, :package_no, :package_type)');
    $statement->execute([
        'id_number' => $id_number,
        'package_no' => $package_no,
        'package_type' => $package_type,
    ]);
    } 
    catch (PDOException $e) {
      echo "DataBase Error: The user could not be added.<br> ".$e->getMessage(); write_file_log($e->getMessage());
      $link = null;
    } catch (Exception $e) {
      echo "General Error: The user could not be added.<br> ".$e->getMessage(); write_file_log($e->getMessage());
      $link = null;
    }
        $link = null;
}
function geo_package($id_number,$package_no,$package_type){
    $link=dbcon();
    $typee= '-';
    try{
    $statement = $link->prepare('INSERT INTO geo_package (id_number,package_no,package_type)
    VALUES (:id_number, :package_no, :package_type)');
    $statement->execute([
        'id_number' => $id_number,
        'package_no' => $package_no,
        'package_type' => $package_type,
    ]);
    } 
    catch (PDOException $e) {
      echo "DataBase Error: The user could not be added.<br> ".$e->getMessage(); write_file_log($e->getMessage());
      $link = null;
    } catch (Exception $e) {
      echo "General Error: The user could not be added.<br>  ".$e->getMessage(); write_file_log($e->getMessage());
      $link = null;
    }
        $link = null;
}
function dbcon(){
    $dbhost = '127.0.0.1';
    $dbname = 'examplename';
    $dbusername = 'exampleuser';
    $dbpassword = 'examplepassword';
    $link = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbusername, $dbpassword);
    $link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $link;
}
function write_file($data){
   $filename = "xxx.txt"; 
   $file = fopen( $filename, "a+" );
   fwrite( $file, $data."\n" );
   fclose( $file );
}
function write_file_log($data){
   $filename = "yyy.txt"; 
   $file = fopen( $filename, "a+" );
   fwrite( $file, $data."\n" );
   fclose( $file );
}

我希望它 24/7 运行,并且只在出现问题时重新启动该套接字。或者我想一次获取设备的 id_number 字段并一遍又一遍地使用它。由于有多个设备,因此为每个设备打开一个单独的套接字。但是当设备的 id_number 为空时,我无法将数据插入数据库。我怎么解决这个问题?

简而言之,当一个套接字正常发送数据时,一段时间后它开始发送空白 id_number 并且我丢失了数据,直到我重新启动程序。其他设备继续工作。

我有两个选择。

第一个选项:当 id_number 为空时重新启动套接字。

第二个选项:当 id_number 为空时重新启动套接字。

但我不知道如何做这些。

另一个问题或捷径是在程序发生错误时再次运行代码。我怎样才能做到这一点?

注意:我在 Centos 7 中运行一个带有服务的 php 程序。

4

0 回答 0