使用xhr向服务器发送请求,如果服务器挂起请求,不立即返回,那么xhr最多可以发送6次,之后不能再发出xhr请求,必须要等前边的xhr得到返回才行。即便不设置回调函数也是如此。
如下,调用了6次np()函数发送请求,服务端把这个"ASDASD"的请求线程suspend,阻塞不返回。那么第7次的bp()发不出去,抓包没有,必须要等前6个np之一得到返回才行。
onLoad(){
this.np();//1
this.np();//2
this.np();//3
this.np();//4
this.np();//5
this.np();//6
this.bp();//7 由于前6个请求没有返回,这个请求等待,发布出去
this.np();
this.np();
},
bp(){
var xhr = new XMLHttpRequest();
xhr.open(“POST”, url, true);
xhr.setRequestHeader(“Content-Type” , “application/x-www-form-urlencoded”);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
cc.log(“bp”);
}
};
xhr.send(“aaa”);
},
np(){
var xhr = new XMLHttpRequest();
xhr.open(“POST”, url, true);
xhr.setRequestHeader(“Content-Type” , “application/x-www-form-urlencoded”);
xhr.send(“ASDASD”);
},
提供下demo和测试平台,看看什么情况。
客户端就是上边的代码,js脚本随便挂一个node上就行。不会弄这个格式,麻烦你看下。
服务端javaweb servlet代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String s=Tools.requestToString(request);
if(s.equals("ASDASD")) {
Thread.currentThread().suspend();
}else {
return;
}}
就是把实体为"ASDASD"的请求挂起,不回复,也不终止;当挂起6个xhr请求后,xhr无法再发送请求。确认是发不出去请求,抓包看不到。
要想6个以后的xhr请求发送出去,或者在服务端恢复对应的请求线程(tr.resume);或者在客户端把xhr给一个成员变量,在合适的时候,this.xhr.abort,比如超时回调函数、node/scene销毁等处。如果服务端的请求线程直接thread.stop,客户端又没有销毁xhr,这个xhr就处于“活死人”状态了,当有这样6个活死人之后,必须重启客户端,否则所有xhr都发不出去了。
我理解是,xhr发送有一个队列;每发送一个,就在队列中加入一个,收到response后移除;当队列数量大于6后,不再发送而是放在缓冲队列里。
不知道是不是有这样的设定。
web-mobil web-desktop都试过。
还请大神帮帮忙看看,多谢多谢。
如果web-mobil和web-desktop测试都有这样的问题,很可能是你服务端的问题,你先使用其他的服务端试试看。
和服务端没关系,是压根没有数据发出去,抓包都抓不到。随便换一个url发送请求,比如就用这个帖子的网址,是先收到6个无权错误回调,顿一下才会收到后边的回调。
确认是浏览器最大并发数做了限制,你可以网上搜索对应浏览器对应的最大并发数,了解一下。
似乎是这个最大并发数的问题。
我使用浏览器直接GET服务器的网页,6/7次STOP或者SUSPEND线程,之后的同请求就发不出去。
并且,只要是相同的HOST地址都不能,即便URL不完全一致。
也就是说,我的域名下的所有url都不能再访问。
使用creator模拟器就不会有这种情况。
但是按最大并发数的说法,我查浏览器的上限是10;并且修改也没用。
另外,在客户端使用xhr.abort(),就可以把阻塞的直接停掉,使后边的请求得以发送,不知道是怎么取消的。
非常感谢!
这个问题有什么好的解决方案吗,应该从服务器入手还是客户端入手呢
我们最近也小概率会遇到堵塞的问题, 我想,可不可以把接口请求的超时改短一点, 比如15秒, 然后 如果超过15秒这个还没有返回,就用 xhr.abort() 把这个接口干掉并且重新请求