TL;DR
MDNS.queryHost()を使う
背景
DHCPを使っているネットワークで通信相手のホストネームがわかっていてもIPがわからない場合や、
諸事情により固定IPにできない時などにmDNSを使って通信相手のIPを取得したい。
やり方
- mDNSサーバを起動する
- queryHostを使って通信相手のIPを探す
#include <ESPmDNS.h>
void setup() {
// … <略> …
// MDNSサーバ起動
// 自分自身の端末名を決めて設定する
MDNS.begin("SELF_HOST_NAME");
// … <略> …
}
void hoge() {
// … <略> …
// .localを含まないhostnameを入力する
// 見つからなかった場合は0.0.0.0が帰ってくる
IPAddress ip = MDNS.queryHost("TARGET_HOST_NAME");
// … <略> …
}
おまけ
https://example.localと通信したい場合や普通にhttps://example.comと通信したい場合が混じってる時用
#include <ESPmDNS.h>
// この関数を呼ぶ前にMDNSサーバを立ち上げておくこと
String resolveMDNS(String url) {
// 末尾が.localではないものはmDNSではない
if(false == url.endsWith(".local")) {
return url;
}
// URLをプロトコルとホストネームに分割する
String protocol="http://";
String hostname = url;
int index = hostname.indexOf("://");
if(0 < index) {
protocol = hostname.substring(0,index+3);
hostname = hostname.substring(index+3);
}
// .localを除いたホストネームからMDNSを解決する
int length = hostname.length();
hostname = hostname.substring(0,length-6);
IPAddress ip = MDNS.queryHost(hostname);
// ipを文字列にして元々のプロトコルと結合する.
String ipStr="";
for (int i = 0; i < 4; i++) {
ipStr += i ? "." + String(ip[i]) : String(ip[i]);
}
return protocol+ipStr; // https://AAA.BBB.CCC.DDDが帰る
}
関数名resolveでよかったのかな?たまに失敗することもあるのでお好みでリトライ機能をつけると良いと思います :D