アクセスポイントが、把握すべきクライアントの状態を以下に記載する。
- IPアドレス
- ブラウザ or センサデバイス
- 接続状態 or 切断状態
- 連続接続時間(バッテリー駆動試験用)
- センサ情報
- タイムアウト識別
アクセスポイントは、一定時間ごとにセンサデバイスからセンサ情報を受け取り、上記の状態とウェッブページを更新してブラウザへ送信する。また、ブラウザからセンシング時間間隔(インターバル)、またはセンシング情報量(データサイズ)の変更要求があった場合に、全ての接続クライアントへ変更を指示する。複数のブラウザが接続する場合もあるので、他のブラウザへの情報提供も必要である。
接続クライアント数、インターバル、データサイズの3つのパラメータが、ネットワークの負荷を決める。逆に言えば、これらの組み合わせで構築するネットワークの限界値を見極めることができる。
センサデバイスが何らかの理由でネットワークから突然切断されると、デバイス側からアクセスポイントへの切断を告知できない。従って、アクセスポイントはデバイスからセンサ情報の提供が一定の待ち時間(タイムアウト時間)が経過してもない場合は、切断したと判断する。
一方、ブラウザの場合はそれを閉じるときに、WebSocketが接続先(アクセスポイント)へ切断の告知を行う。しかしながら、ブラウザを起動しているPCやスマートフォンなどが、ブラウザ起動のまま接続中のアクセスポイントを切り替えたり遮断してしまうと、アクセスポイントはブラウザの切断を感知できない。そこで、ウェブページ送信処理の成功/失敗により、ブラウザ切断を判断する必要がある。
上記に述べた切断の判断を適切に行わないと、切断中のクライアントへ情報を送ることになり、アクセスポイントには不要な負荷がかかってしまう。これにより、ネットワーク全体のパフォーマンスが低下する。
以下に、WebSocket通信に関係する変数を中心に記述する。WebSocketの仕様としては、送受信可能な最大データサイズは特に明記されていないが、ESP32のライブラリーとしては、WebSockets.hにWEBSOCKETS_MAX_DATA_SIZEとして(15 * 1024)と定義されている。すなわち、一度に送受信できるデータサイズは15360byteである。
// グローバル変数
int unitTime = 100; // 100msec基本割込み
bool oneSecFlag = false; // 1秒経過フラグ
int intervalBase = 10; // 基本インターバル 100msec x 10 = 1000msec
uint8_t datasizeBase = 0; // 基本データサイズ 1024byte x N(例外0:1byte)
bool webFlag = false; // ウェブブラウザ定期配信フラグ
bool intervalFlag = false; // インターバル更新告知フラグ
bool datasizeFlag = false; // データサイズ更新告知フラグ
int timeoutMAX = 3; // デバイス非応答タイムアウト3秒
unsigned long setupCounter = 0; // ESP32起動カウンター(毎秒更新)
// クライアント状態変数構造体
typedef struct {
uint8_t Address[CLIENT_MAX]; // IPアドレス末尾
uint8_t Station[CLIENT_MAX]; // 未確認:0, ブラウザ:1, デバイス:2 識別
uint8_t Connect[CLIENT_MAX]; // 切断:0, 接続:1, データ受信開始:2 識別
uint32_t Elapsed[CLIENT_MAX]; // 連続接続時間(秒単位)
uint8_t GetData[CLIENT_MAX]; // 受信先頭1byteデータ
uint8_t TimeOut[CLIENT_MAX]; // 非応答タイムアウトカウンター
} client;
client clientSTAT;
// 通信速度測定用バッファ
// WEBSOCKETS_MAX_DATA_SIZE (15 * 1024) ⇒ 15,360 (WebSockets.hで定義)
uint8_t buffer[WEBSOCKETS_MAX_DATA_SIZE];
// タイマー管理用の構造体ポインター
hw_timer_t *timer = NULL;