Я работаю над проектом геолокации на PHP, использую сокеты, у меня проблема, объясняю: клиент (ящик GPS) отправляет свой идентификатор (IMEI) и ждет ответа сервера (сообщение '01'), после получения (сообщение '01 ') клиент отправляет данные на сервер, и сервер сохраняет их в база данных. здесь он хорошо работает только с одним клиентом и даже с несколькими подключенными клиентами, но проблема, если в то время, когда сервер ожидает данных GPS-клиента (A), подключается другой клиент (B), поэтому сервер, когда он получает данные GPS client (A), он сохранит их с именем клиента (B), потому что в моем коде сервер хранит данные GPS с именем последнего подключенного клиента.
<?php
error_reporting(E_ALL);
set_time_limit(0);
$ip='192.168.1.1';
$port=135;
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) ;
socket_bind($sock, $ip , $port) ;
socket_listen ($sock);
echo "Waiting for incoming connections... \n";
$tab=array();
$client = array($sock);
while (true)
{
$read = $client;
$write=null ;
$except=null ;
if (socket_select($read , $write , $except , 0)<1)
continue;
if (in_array($sock, $read))
{
$client[] = $newsock = socket_accept($sock);
socket_getpeername($newsock, $address, $port) ;
echo "Client $address : $port is now connected to us. \n";
echo "Waiting for incoming data... \n";
$key = array_search($sock, $read);
unset($read[$key]);
}
foreach ($read as $read_sock)
{
$input = socket_read($read_sock, 102401,PHP_BINARY_READ) ;
if ($input == false)
{
$key = array_search($read_sock, $client);
unset($client[$key]);
echo "client disconnected.\n";
continue;
}
if (!empty($input))
{
if (strlen($input)==17){
//$input=bin2hex($input) ;
$input = substr($input,2,strlen($input));
$imei_verif=$input ;
echo "Le 1er socket reçu : \n";
echo "IMEI =$input"."\n"."length = ".strlen($input);
//$response=hex2bin('01');
$response='01';
echo "\n La réponse est 01 \n";
$len = strlen($response);
$res_write=socket_send($read_sock ,$response,$len,0);
echo "GPS informations ....... \n";
$conn = new mysqli("localhost", "root", "", "fma120");
$result = $conn->query("SELECT * FROM vehicule WHERE imei='$imei_verif'");
$outp = $result->fetch_assoc();
$identifiant= $outp['identifiant'] ;
$matricule=$outp['matricule'];
echo $identifiant."\n";
echo $matricule;
}
else {
echo "Client $address : $port is now connected to us. \n";
$input=bin2hex($input) ;
$payload=$input ;
$crc = substr($payload, strlen($payload) - 8, 8);
echo "crc = ".$crc ."\n" ;
$avlDataWithChecks = substr($payload, 16, -8);
if (substr($avlDataWithChecks, 2, 2) !== substr($avlDataWithChecks, strlen($avlDataWithChecks) - 2, 2))
{
echo "First element count check is different than last element count check \n ";
echo " informations = " .$input ."\n" ;
}
if (substr($avlDataWithChecks, 2, 2) == substr($avlDataWithChecks, strlen($avlDataWithChecks) - 2, 2) )
{
echo"voila ....................... GPS informations réçu : \n" ;
echo"input = ".$input ."\n" ;
echo "length = ".strlen($input);
echo "avlDataWithChecks = ".$avlDataWithChecks ."\n" ;
$numberOfElements = hexdec(substr($avlDataWithChecks, 2, 2));
echo "numberOfElements = " .$numberOfElements ."\n" ;
$avlData = substr($avlDataWithChecks, 4, -2);
$position = 0;
$resultData = [];
$dateTime = new DateTime();
$timestamp = hexdec(substr($avlData, $position, 16)) / 1000;
$timestamp+= 7200;
echo "timestamp = ".$timestamp . "\n";
$dateTime -> setTimestamp(intval($timestamp));
echo "dateteTime = " .$dateTime->format('U = Y-m-d H:i:s') . "\n";
$position += 16;
$priority = (int)hexdec(substr($avlData, $position, 2));
echo" priority = " .$priority ."\n" ;
$position += 2;
$longitude = substr($avlData, $position, 8);
$longitude = (float)(hexdec($longitude) / 10000000);
echo" longitude = " .$longitude ."\n" ;
$position += 8;
$latitude = substr($avlData, $position, 8);
$latitude = (float)(hexdec($latitude) / 10000000);
echo" latitude = " .$latitude ."\n" ;
$position += 8;
$altitude = (int)hexdec(substr($avlData, $position, 4));
echo" altitude = " .$altitude ."\n" ;
$position += 4;
$angle = (int)hexdec(substr($avlData, $position, 4));
echo" angle = " .$angle ."\n" ;
$position += 4;
$satellites = (int)hexdec(substr($avlData, $position, 2));
echo" satellites = " .$satellites ."\n" ;
$position += 2;
$speed = (int)hexdec(substr($avlData, $position, 4));
echo" speed = " .$speed ."\n" ;
echo "\n La réponse est $numberOfElements \n";
$output = sprintf("%08X", $numberOfElements) ;
$output2=$output ;
echo "avant l'envoie = " .$output2 ."\n" ;
$output2 =hex2bin($output2);
$len = strlen($output2);
$res_write=socket_send($read_sock,$output2,$len,0);
echo "apres l'envoie = " .$output2 ."\n" ;
//echo $identifiant."\n";
//$output2 =hex2bin($output2);
$len = strlen($output2);
$res_write=socket_send($read_sock ,$output2,$len,0);
echo "apres l'envoie = " .$output2 ."\n" ;
try
{
$bdd = new PDO('mysql:host=localhost;dbname=fma120;charset=utf8', 'root', '');
}
catch(Exception $e)
{
die('Erreur : '.$e->getMessage());
}
$bdd->exec("INSERT INTO gps_data(client,matricule,imei, timestamp, longitude, latitude, altitude,angle,satellites,speed,etat,n_of_elem) VALUES('$identifiant','$matricule','$imei_verif', '$timestamp', '$longitude', '$latitude', '$altitude','$angle','$satellites','$speed','0','$numberOfElements')");
echo 'Strored in the data base';
}
}
}
}
}
?>






ну, вам нужно сохранить взаимосвязь между данными, например, вы можете создать мульти-массив с уникальным идентификатором клиента в качестве ключа. вам также необходимо сохранить идентификатор клиента <=> отношения клиентского сокета.
это не так сложно реализовать, но чтобы все связанные вещи были организованы, поэтому сделайте это как можно проще (я бы рекомендовал создать класс, который будет содержать каждую информацию, связанную с подключением, чтобы вы не перебирали абстрактные ресурсы сокета, а вместо этого перебирали логическое соединение объект, который значительно упрощает обработку)
например
class ConnectionInfo
{
public $Socket;
public $ID;
}
или же
$Connections = [];
$Connections[$ID]['Socket'] = $Socket;
проблема в том, что данные GPS не содержат никакой информации о клиенте, поэтому я не могу знать, что эти данные связаны с каким клиентом, возможно, если я знаю IP-адрес источника сообщения и после сравнения его с IP-адресом первого соединение (когда клиент отправляет imei) .
Я могу сохранить идентификатор первого подключения, но как я могу узнать информацию о 2-м подключении того же клиента, чтобы сравнить их с сохраненным идентификатором?