目的:
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 件のコメント:
コメントを投稿