Files
cpp-httplib/docs-src/pages/ja/cookbook/e04-sse-client.md
2026-04-10 19:02:44 -04:00

3.3 KiB
Raw Blame History

title, order, status
title order status
E04. SSEをクライアントで受信する 50 draft

cpp-httplibにはsse::SSEClientという専用のクラスが用意されています。自動再接続、イベント名別のハンドラ、Last-Event-IDの管理まで面倒を見てくれるので、SSEを受信するときはこれを使うのが一番ラクです。

基本の使い方

#include <httplib.h>

httplib::Client cli("http://localhost:8080");
httplib::sse::SSEClient sse(cli, "/events");

sse.on_message([](const httplib::sse::SSEMessage &msg) {
  std::cout << "data: " << msg.data << std::endl;
});

sse.start(); // ブロッキング

Clientと接続先パスを渡してSSEClientを作り、on_message()でコールバックを登録します。start()を呼ぶとイベントループが走り、接続が切れると自動で再接続を試みます。

イベント名で分岐する

サーバー側でevent:を付けて送られてくる場合は、on_event()で名前ごとにハンドラを登録できます。

sse.on_event("message", [](const auto &msg) {
  std::cout << "chat: " << msg.data << std::endl;
});

sse.on_event("join", [](const auto &msg) {
  std::cout << msg.data << " joined" << std::endl;
});

sse.on_event("leave", [](const auto &msg) {
  std::cout << msg.data << " left" << std::endl;
});

on_message()は、名前なし(デフォルトのmessageイベント)を受け取る汎用ハンドラとして使えます。

接続イベントとエラーハンドリング

sse.on_open([] {
  std::cout << "connected" << std::endl;
});

sse.on_error([](httplib::Error err) {
  std::cerr << "error: " << httplib::to_string(err) << std::endl;
});

接続確立時やエラー発生時にもフックを挟めます。エラーハンドラが呼ばれても、SSEClientは内部で再接続を試みます。

非同期で動かす

メインスレッドを塞ぎたくない場合はstart_async()を使います。

sse.start_async();

// メインスレッドは別の仕事を続ける
do_other_work();

// 終わったら止める
sse.stop();

start_async()は裏でスレッドを立ち上げてイベントループを回します。stop()でクリーンに止められます。

再接続の設定

再接続間隔や最大試行回数を調整できます。

sse.set_reconnect_interval(5000);    // 5秒
sse.set_max_reconnect_attempts(10);  // 10回まで0=無制限)

サーバー側でretry:フィールドを送っていると、そちらが優先されます。

Last-Event-IDの自動管理

SSEClientは受信したイベントのidを内部で保持していて、再接続時にLast-Event-IDヘッダーとして送ってくれます。この挙動はサーバー側でid:付きイベントを送っていれば自動で有効になります。

std::cout << "last id: " << sse.last_event_id() << std::endl;

現在のIDはlast_event_id()で参照できます。

Note: SSEClientのstart()はブロッキングなので、単発のツールならそのまま使えますが、GUIアプリやサーバーに組み込むときはstart_async() + stop()の組み合わせが基本です。

サーバー側の実装はE01. SSEサーバーを実装するを参照してください。