早上好/晚上好,
我正在通过ajax-java实现客户端 - 服务器之间的长池化。并且长轮询在客户端正常工作,并且每30秒抛出一个新连接,并且前一个连接被中止。但问题是,在服务器端,所有这些请求/线程都保持活动状态,直到我们有东西返回客户端。但就像我说客户可能不再听了。这里有一些代码:
客户端:
// Long Polling (Recommened Technique - Creates An Open Connection To Server ∴ Fast)
(function poll(){
var tenantName = $("#tenantName").val();
$.ajax({
method:"GET",
url: "url",
success: function(data){
if (data === true) {
bootbox.alert("Page has been modify <a href='javascript:void(0)' onclick='reload()'>reload</a>");
}
}, dataType: "json", complete: poll, timeout: 60000 });
})();
服务器:
/**
* @return
*/
@RequestMapping(method = RequestMethod.GET)
@ResponseBody
public Boolean getSubStepStatus(@RequestParam("subStep") String subStep,
@RequestParam("tenantId") String tenantId) {
if (!isInStep(subStep, tenantId)) {
tenantsInStep.get(subStep).add(tenantId);
}
while (true) {
String modifierTenantId = stepModifyByTenant.get(subStep);
if (modifierTenantId != null && !modifierTenantId.equals(tenantId) && !isInStep(subStep, tenantId)) {
tenantsInStep.get(subStep).remove(tenantId);
return true;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
问题就像我说的那样,所有线程每30秒在服务器端增长和增长,使用这种技术我做错了什么?
答案 0 :(得分:2)
Thread.sleep(1000);
不是在Java中进行长轮询的方法。这样做的方法是将请求置于异步模式,注册一个监听器,并放弃工作线程。
答案 1 :(得分:0)
您似乎在使用SpringMVC,我认为Web应用程序在servlet引擎(例如Tomcat或Jetty)中运行。
处理请求时,服务器无法检测客户端是否仍在侦听,除非它尝试发送响应数据(see also this question)。您的控制器代码执行可能无限循环(这本身就是一个坏主意)。只要此循环正在运行,就不会发送响应数据,因此即使客户端已断开连接,控制器也将继续循环。
如果你想保持当前的设计,一个简单的解决办法就是防止无限循环,即在经过一定数量的迭代或经过的时间后中断并发送false
作为响应。然后客户端必须重新连接才能开始新的轮询周期。