はじめに
IoTデバイスをIPアドレスを使って識別しようとしている方,デバイスのIPアドレスをサーバ側で取得したい方向けになります.
環境
- IoTデバイス(ESP-WROOM-32)
- ファームウェア(MicroPython1.3)
- サーバ(Ubuntu18.04)
- Webサーバ(Apache2)
- PHP(PHP7.4)
※Apache2を起動して/var/www/html/にPHPプログラム(今回はreceive.php)を置いておくことが前提です.
ソースコード(ESP32)
今回はESP32で適当なJSONデータのPOST送信をし,サーバで送信元のIPアドレスを取得してレスポンスとしてそのIPアドレスを返すようなプログラムにしました.
post.py
import urequests
import ujson
#送信先のURLの指定
#"XXX.XXX.XXX.XXX"にURLを入れる
url = 'http://XXX.XXX.XXX.XXX/receive.php'
#データをDICT型で宣言
obj = {"value" : 123, "text" : "abc"}
#jsonデータで送信するという事を明示的に宣言
header = {'Content-Type' : 'application/json'}
#オブジェクトをJSONに変換し,HTTPリクエストをPOSTとして送信
res = urequests.post(
url,
data = ujson.dumps(obj).encode("utf-8"),
headers = header
)
#サーバ側からのレスポンスを受け取って表示(jsonのデコードも一緒にしている)
print (res.json())
#終了
res.close()
ソースコード(サーバ)
送信元のIPアドレスは$_SERVER[REMOTE_ADDR]
に入っているのでそれを変数に入れるなりする.
receive.php
<?php
//送られてきたPOSTデータを受け取って,JSONデータをデコードして$inに入れる.
$json_string = file_get_contents('php://input');
$in = json_decode(stripslashes($json_string),true);
//送られてきたデータを取り出す
$value = $in["value"]; // = 123
$text = $in["text"]; // = abc
//$_SERVER変数を使って送信元のIPアドレスを取得する
//レスポンスを取得したIPアドレスとし,それをJSONとして再度エンコード
//そして送信元(ESP32)へ返す.
$ipAddress = $_SERVER['REMOTE_ADDR'];
//AWS ELBを使用している場合はELBのIPアドレスを取得してしまうので
//以下のようにして元のIPアドレスを取得する
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
$ipAddress = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
}
//IPアドレスをエンコードして返す
echo json_encode($ipAddress);
?>
実行結果
micropythonのWEB REPLで実行したところ,IPアドレスが返ってきました.
>>> execfile("post.py")
YYY.YYY.YYY.YYY // <- ESP32のIPアドレス
参考
この記事は以下の記事を参考に書いています
[1]
ESP32からMicropythonでHTTPリクエスト(POST)でデータを送信し,PHP(サーバ)で受け取る