目的:
WEBからの XHR アクセス を繰り返していると ESP32 へ接続ができなくなることがある為、原因/対策を探る。現象:
WEB から スライダーで値の送信 や、ESP32 の状態のポーリング を XHR を使用して行っていると、途中で ESP32 への接続ができなくなる。( 例えば、 LED調光_WEBからと外付けのボリュームからを切り替えて調光 )
原因:
原因は不明。[2019/11/28 追記]
Arduino core for the ESP32 の Ver 1.0.2 の問題と推定。
Ver 1.0.3 では 問題は発生しない模様。
要因等:
短時間の確認しかできていないが、XHR で複数の要求が発生した場合に 接続できなくなる模様。XHR の発行を 1つだけに制限すると 現象がまた、Arduino core for the ESP32 の Ver 1.0.2 で発生し、Ver 1.0.0, 1.01 では 継続して動作できる。
Arduino core for the ESP32 Ver 1.0.2 の問題と推定。
対応方法:
(1) Ver
但し、自分の環境では、1.0.1 は softAP での接続が できない。
(2) XHR の発行を 1つに制限。(但し、頻度が下がるのみ)
"LED調光_WEBからと外付けのボリュームからを切り替えて調光" の HTML での 修正例を以下に示す。
<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'> <style> #base {font-size:16pt;text-align:center;width:300px;border:solid 4px #93ff93; } #radio_box {font-size:12pt;float:left ;text-align:left; width:45%; } #disp_box {font-size:12pt;float:right;text-align:left; width:50%; } #brightness {font-size:12pt;text-align:right; } #val_box {font-size:12pt;text-align:center; clear:both ;} #ctl_box {text-align:center; } input.radio {margin-left:8px; width:30px;} input.value {margin-left:8px; width:30px;} input.setbutton{margin-left:8px; width:40px;} input.slider {margin-left:8px; width:250px;} input.button {margin:0px 15px; width:100px;} </style> <title>Color LED Controller</title></head> <body> <div id="base"> <p>LED ON/OFF</p> <div id="radio_box"> <form method="get"> <input class='radio' type='radio' name='remote' id="rad_lo" value='local' $checked_lo onclick='disp_ctrl(this.value); submit(this.value)'>local<br> <input class='radio' type='radio' name='remote' id="rad_rm" value='remote' $checked_rm onclick='disp_ctrl(this.value); submit(this.value)'>remote<br> </form> </div> <div id="disp_box"> <span> brightness value</span><br> <div id="brightness"><output id="o1">$led_brightness</output></div> </div> <div id="val_box"> <form method="get"> <span style="font-size:10pt;"> LED brightness (0-255)</span> <input class='value' type='text' name='led_v' value=$led_brightness id='led_v' disabled> <input class='setbutton' type='submit' name='set' id='set' value='SET' disabled> </form> <form method='get'> <input class="slider" type="range" name='led_s' id='led_s' value=$led_brightness min="0" max="255" step="1" disabled onchange="setval(this.value);" oninput="setval(this.value)"; onmouseup="submit(this.form)": ontouchend="submit(this.form)"> </form> </div> <div id="ctl_box"> <form method='get'> <input class='button' type='submit' name='on' id="on" value='ON' disabled > <input class='button' type='submit' name='off' id="off" value='OFF' disabled><br> </form> </div> </div> <script> var polling = null ; var sendbusy = 0 ; function setval(ledval){ if (sendbusy == 0) { sendbusy = 1 ; var xhr = new XMLHttpRequest(); xhr.open("get", "?slid="+ledval ); xhr.setRequestHeader('Cache-Control', 'no-cache'); xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhr.responseType = 'document' ; xhr.onreadystatechange = function() { if( (xhr.readyState == 4) && (xhr.status == 200) ) { document.getElementById('led_v').value = xhr.response.getElementById("output1").innerHTML; document.getElementById('o1').innerHTML = xhr.response.getElementById("output1").innerHTML; setTimeout( function() { sendbusy = 0 ; },100) ; } } ntimeout = function(e) { xhr.abort() ; setTimeout( function() { sendbusy = 0 ; },100) ; } xhr.send(); } } function getval(){ if (sendbusy == 0) { sendbusy = 1 ; var xhrget = new XMLHttpRequest(); xhrget.open("get", "?pol" ); xhrget.setRequestHeader('Cache-Control', 'no-cache'); xhrget.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT'); xhrget.responseType = 'document' ; xhrget.onreadystatechange = function() { if( (xhrget.readyState == 4) && (xhrget.status == 200) ) { document.getElementById('o1').innerHTML = xhrget.response.getElementById("output1").innerHTML; setTimeout( function() { sendbusy = 0 ; },100) ; } } ntimeout = function(e) { xhrget.abort() ; setTimeout( function() { sendbusy = 0 ; },100) ; } xhrget.send(); } } function disp_ctrl( radioid ) { if(radioid == 'remote') { document.getElementById('led_v').disabled = false; document.getElementById('set').disabled = false; document.getElementById('led_s').disabled = false; document.getElementById('on').disabled = false; document.getElementById('off').disabled = false; clearInterval(polling); } else { document.getElementById('led_v').disabled = true; document.getElementById('set').disabled = true; document.getElementById('led_s').disabled = true; document.getElementById('on').disabled = true; document.getElementById('off').disabled = true; polling = setInterval(getval,100) ; } } window.onload = function() { if(document.getElementById("rad_rm").checked) { document.getElementById('led_v').disabled = false; document.getElementById('set').disabled = false; document.getElementById('led_s').disabled = false; document.getElementById('on').disabled = false; document.getElementById('off').disabled = false; clearInterval(polling); } else if(document.getElementById("rad_lo").checked) { document.getElementById('led_v').disabled = true; document.getElementById('set').disabled = true; document.getElementById('led_s').disabled = true; document.getElementById('on').disabled = true; document.getElementById('off').disabled = true; polling = setInterval(getval,100) ; } } </script> </body> </html>
XHR 送信中のフラグを用意し、送信中は新たな送信を行わない様にする。
XHR は スライダーでの送信と ボリューム値のポーリングの 2種を行っているが、フラグは共通で、常に 1つしか送信しない様にしている。
応答受信後、少しまってから フラグを解除する必要がある。(この例の待ち時間 100mS は暫定値。どの程度待てばよいかは未確認)
0 件のコメント:
コメントを投稿