通常、GPS座標は、以下など、浮動小数点数で表されます。
緯度:31.2304
経度:121.4737
タイムスタンプ:たとえば、UNIXタイムスタンプ1716720000
JSONなどの文字列形式で直接送信すると、サイズが大きく、帯域幅が限られているIoTデバイスには適していません。 Pack()関数を使用して、これらの値をバイナリ形式の固定長データパケットにパッケージ化し、帯域幅を保存し、レシーバー側に正確に復元できます。
Pack()は、PHPの組み込み関数であり、データをバイナリ文字列に変換するために使用され、ネットワーク通信、ファイルストレージなどによく使用されます。基本的な構文は次のとおりです。
string pack(string $format, mixed ...$values)
パラメーター$フォーマットは、次の値のタイプと順序を指定するフォーマット制御文字列です。たとえば、次のようになります。
F :32ビットフローティングポイント番号(リトルエンディアン)
D :64ビットフローティングポイント番号
N :32ビットの符号なし整数(ビッグエンディアン)
V :32ビットの署名されていない整数(リトルエンディアン)
互換性とデータのコンパクトさについては、以下を使用していると仮定します。
緯度:フロート(4バイト、リトルエンディアン)
経度:フロート(4バイト、小さなエンディアン)
タイムスタンプ:UINT32(4バイト、リトルエンディアン)
次のコードを使用して、このデータをパッケージ化できます。
<?php
// GPSデータ
$latitude = 31.2304;
$longitude = 121.4737;
$timestamp = time(); // 現在のタイムスタンプ
// 小エンディアン形式を使用したパッケージング(latitude: float, longitude: float, timestamp: uint32)
$binaryData = pack('ffV', $latitude, $longitude, $timestamp);
// オプション:将打包后的二进制データ进行Hexコーディング,見るのは簡単です
$hexData = bin2hex($binaryData);
echo "打包后的二进制データ为: $hexData\n";
?>
このコードは以下を出力します。
打包后的二进制データ为: 9ad4fc3f7089514270128c66
各セグメントは、それぞれパッケージ緯度、経度、タイムスタンプに対応しています。 unpack()を使用してサーバーに戻すことができます。
<?php
$receivedData = $binaryData; // デバイスから受信されたと仮定します
$unpacked = unpack('flatitude/flongitude/Vtimestamp', $receivedData);
print_r($unpacked);
?>
デバイス側は、同じバイナリ構造を使用してデータをパッケージ化し、MQTT、HTTP Post、またはUDPを介してサーバーにアップロードできます。例えば:
$url = "https://m66.net/api/receive.php";
$data = $binaryData;
$options = [
'http' => [
'method' => "POST",
'header' => "Content-Type: application/octet-stream\r\n",
'content' => $data
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
echo "サーバーの応答: $response\n";
サーバー側は、PHP://入力を介して元のバイナリデータを読み取ることができます。
Pack()のフローティングポイント番号形式は、さまざまなプラットフォームによってわずかに異なる場合があり、小エンディアンまたは大エンディアンを均一に使用し、形式を記録する必要があります。
デバイスとサーバーが同じバイト順序を使用していることを確認してください。
送信されたデータ構造が複雑な場合は、データヘッダー識別子(タイプ、バージョン番号など)を追加することをお勧めします。