IoTプロトコル

HTTP / HTTPS

Web標準の通信プロトコル。

概要

HTTP(HyperText Transfer Protocol)は、World Wide Webの基盤を成すアプリケーション層プロトコルです。1991年にTim Berners-Leeが最初のバージョンを定義して以来、インターネット上でHTMLドキュメント・画像・API応答など、あらゆる種類のデータをやり取りする標準手段として使われ続けています。

HTTPS(HTTP Secure)はHTTPにTLS(Transport Layer Security)による暗号化・認証を組み合わせたものです。現代のWebではHTTPSが標準となっており、IoT機器がクラウドAPIと通信する際も基本的にHTTPSを使います。

組み込み・IoT分野では以下のような場面でHTTP/HTTPSが使われます。

  • クラウドのREST APIへのセンサーデータ送信
  • ファームウェアのダウンロード(OTA)
  • Webベースの管理画面(HTTPサーバーを内蔵したマイコン)
  • Webhookによるイベント通知

Raspberry PiやESP32など処理能力のあるデバイスではフル機能のHTTPクライアントが動きますが、超小型マイコンではメモリ制約からlibcurlやhttpclientなどの軽量ライブラリを使います。


歴史・背景

バージョンの変遷

バージョン主な特徴
HTTP/0.91991GETのみ、テキストのみ
HTTP/1.01996ヘッダー追加、POST/HEADサポート
HTTP/1.11997持続接続、パイプライン、チャンク転送
HTTP/22015バイナリフレーム、多重化、ヘッダー圧縮
HTTP/32022QUIC(UDP)ベース、接続確立高速化

HTTP/1.1は長年の主流でしたが、1リクエストごとに1レスポンスを待つ「HOL(Head-of-Line)ブロッキング」が問題でした。HTTP/2は多重化でこれを解消し、HTTP/3はQUICプロトコルによってTCPのハンドシェイクコストまで排除しました。

IoTとHTTPの関係

スマートフォンやシングルボードコンピュータ(Raspberry Pi等)の普及により、IoT機器がHTTPクライアントとしてクラウドAPIに直接接続するパターンが一般化しました。AWS IoT、Azure IoT Hub、Google Cloud IoTはいずれもHTTPS(REST)を主要プロトコルの一つとしてサポートしています。


技術仕様

HTTPリクエスト構造

POST /api/v1/sensors HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGc...
Content-Length: 42

{"device_id":"ESP32-01","temperature":25.3}

HTTPレスポンス構造

HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/sensors/measurements/1234

{"id":1234,"timestamp":"2025-01-15T12:00:00Z","status":"stored"}

ステータスコード

コード意味IoTでの典型例
200 OK成功データ取得成功
201 Created作成成功センサーデータ登録成功
400 Bad Requestリクエスト不正JSONパースエラー
401 Unauthorized認証失敗トークン無効
403 Forbidden権限なしデバイス未登録
404 Not FoundリソースなしデバイスID不存在
429 Too Many Requestsレート制限送信頻度超過
500 Internal Server Errorサーバーエラーバックエンド障害

TLS(HTTPS)の仕組み

Client                          Server
  |                               |
  |-- ClientHello --------------->|  (TLS 1.3)
  |<-- ServerHello + Certificate -|
  |<-- Finished ------------------|
  |-- Finished + Application Data>|  (ここからHTTP暗号化通信)

TLS 1.3では従来の1.5往復から0.5往復(1-RTT)にハンドシェイクが短縮され、セッション再開では0-RTTも可能です。組み込み機器では接続確立のコストが大きいため、Keep-AliveやTLSセッション再利用が重要です。

HTTPヘッダーの主要フィールド(IoT関連)

ヘッダー用途
Content-Typeペイロード形式(application/json等)
Authorization認証トークン(Bearer/Basic)
X-API-KeyAPIキー認証
If-None-MatchETagによる条件付きGET(OTAに有用)
Content-Encodinggzip圧縮等
Keep-Alive持続接続設定

動作原理

TCP接続とKeep-Alive

HTTP/1.1はデフォルトでTCP接続を維持します(Keep-Alive)。マイコンでHTTPS通信を繰り返す場合、接続を使い回すことでTLS再ハンドシェイクのコストを削減できます。

// ESP-IDF(ESP32)でのHTTPS接続維持
esp_http_client_config_t config = {
    .url = "https://api.example.com",
    .cert_pem = server_cert,
    .keep_alive_enable = true,
    .keep_alive_idle = 5,
    .keep_alive_interval = 5,
    .keep_alive_count = 3,
};

esp_http_client_handle_t client = esp_http_client_init(&config);

// 複数回のリクエストで同一接続を再利用
for (int i = 0; i < 10; i++) {
    esp_http_client_set_url(client, "https://api.example.com/data");
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_post_field(client, json_buf, strlen(json_buf));
    esp_http_client_perform(client);
    
    vTaskDelay(pdMS_TO_TICKS(1000));
}

esp_http_client_cleanup(client);

チャンク転送(ファームウェアOTA)

大容量ファームウェアをメモリに一度に収めずにダウンロードするチャンク転送。

// Chunked Transfer Encoding でOTAデータを受信
esp_http_client_open(client, 0);  // GETリクエスト送信
int content_length = esp_http_client_fetch_headers(client);

int data_read = 0;
char *buf = malloc(CHUNK_SIZE);
while (1) {
    int len = esp_http_client_read(client, buf, CHUNK_SIZE);
    if (len <= 0) break;
    
    // OTAパーティションへ書き込み
    esp_ota_write(ota_handle, buf, len);
    data_read += len;
}
free(buf);

WebSocketアップグレード

HTTPはWebSocketへのアップグレードにも使われます。最初はHTTPで接続し、Upgradeヘッダーで切り替えます(詳細はWebSocketを参照)。

GET /ws HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

用途・ユースケース

クラウドREST API連携

ESP32やRaspberry Piからセンサーデータをクラウドに送る最もシンプルな方法です。

# MicroPython(Raspberry Pi Pico W)での例
import urequests
import json

data = {
    "device": "pico_w_01",
    "temperature": 24.5,
    "humidity": 60.2
}

headers = {
    "Content-Type": "application/json",
    "X-API-Key": "your-api-key"
}

response = urequests.post(
    "https://api.example.com/measurements",
    json=data,
    headers=headers
)

if response.status_code == 201:
    print("送信成功:", response.json())
response.close()

組み込みWebサーバー(管理画面)

ESP32やSTM32はHTTPサーバーを内蔵し、ブラウザから設定変更・状態確認ができます。

// ESP-IDFのhttpd使用例
static esp_err_t status_get_handler(httpd_req_t *req) {
    char json[256];
    snprintf(json, sizeof(json),
             "{\"uptime\": %lld, \"temp\": %.1f, \"heap\": %d}",
             esp_timer_get_time() / 1000000,
             get_temperature(),
             esp_get_free_heap_size());
    
    httpd_resp_set_type(req, "application/json");
    httpd_resp_sendstr(req, json);
    return ESP_OK;
}

httpd_uri_t status_uri = {
    .uri       = "/api/status",
    .method    = HTTP_GET,
    .handler   = status_get_handler,
};
httpd_register_uri_handler(server, &status_uri);

OTA(ファームウェア更新)

HTTPSで署名済みファームウェアをダウンロードし、フラッシュに書き込むOTAの実装に使われます。

Webhook通知

センサーが閾値を超えたときに、SlackやTeamsのWebhook URLにHTTP POSTで通知する実装もよく使われます。


実装・開発のポイント

証明書管理

HTTPSにはルートCA証明書が必要です。マイコンのフラッシュに組み込む際は証明書のサイズと有効期限に注意が必要です。

// 証明書をバイナリとしてフラッシュに埋め込む(ESP-IDF)
extern const uint8_t server_cert_pem_start[] asm("_binary_server_cert_pem_start");
extern const uint8_t server_cert_pem_end[]   asm("_binary_server_cert_pem_end");

esp_http_client_config_t config = {
    .cert_pem = (const char *)server_cert_pem_start,
    .cert_len = server_cert_pem_end - server_cert_pem_start,
};

タイムアウトと再試行

組み込み環境では接続タイムアウトを適切に設定し、指数バックオフで再試行します。

#define HTTP_TIMEOUT_MS     10000
#define MAX_RETRY           3
#define RETRY_BASE_DELAY_MS 1000

int send_with_retry(esp_http_client_handle_t client) {
    for (int i = 0; i < MAX_RETRY; i++) {
        esp_err_t err = esp_http_client_perform(client);
        if (err == ESP_OK) {
            int status = esp_http_client_get_status_code(client);
            if (status == 200 || status == 201) return 0;
        }
        // 指数バックオフ
        vTaskDelay(pdMS_TO_TICKS(RETRY_BASE_DELAY_MS * (1 << i)));
    }
    return -1;
}

メモリ最適化

HTTPヘッダーとボディ全体をRAMに保持しないよう、ストリーミング受信を使います。特にOTAの際は重要です。


他技術との比較

項目HTTP/HTTPSMQTTCoAPWebSocket
トランスポートTCPTCPUDPTCP(HTTP経由)
通信モデルReq/ResPub/SubReq/Res双方向
ブラウザ対応×
制約機器適合
標準化RFC 9110-OASISRFC 7252RFC 6455
暗号化TLS(HTTPS)TLSDTLSTLS(WSS)

REST API設計と組み合わせることで、IoTデバイスとWebサービスのシームレスな統合が実現できます。双方向リアルタイム通信が必要な場合はWebSocketへのアップグレードを検討します。

関連用語

参考リンク