Клиент и сервер php сокет
Я работаю над проектом геолокации с PHP, я использую сокеты У меня есть проблема, я объясняю: клиент (box 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';
}
}
}
}
}
?>
2 ответа
Проблема в том, что данные gps не содержат никакой информации о клиенте, поэтому я не могу знать, связаны ли эти данные с каким клиентом, возможно, если я знаю ip-адрес источника сообщения и после того, как я сравню его с ip-адресом первого соединение (когда клиент отправляет imei).
Я могу сохранить идентификатор первого соединения, но как узнать информацию о втором соединении того же клиента, чтобы сравнить их с сохраненным идентификатором?
Ну, вам нужно хранить отношения между данными, например, вы можете создать мульти-массив с уникальным идентификатором клиента в качестве ключа. вам также нужно сохранить идентификатор клиента <=> отношение сокета клиента.
это не так сложно реализовать, но держать все связанные вещи организованными, поэтому сделайте это как можно проще (я бы порекомендовал создать класс, содержащий информацию, относящуюся к каждому соединению, чтобы вы не перебирали абстрактные ресурсы сокета, а перебирали логическое соединение объект, который делает его намного проще в обращении)
например
class ConnectionInfo
{
public $Socket;
public $ID;
}
или же
$Connections = [];
$Connections[$ID]['Socket'] = $Socket;