具有延迟结果的Spring长轮询
我有一个SpringMVC3.2应用程序,我需要为这个Web服务添加一个长轮询,以便进行实时聊天。 我看了这篇文章 TopicRestController:具有延迟结果的Spring长轮询,spring,spring-mvc,asynchronous,long-polling,Spring,Spring Mvc,Asynchronous,Long Polling,我有一个SpringMVC3.2应用程序,我需要为这个Web服务添加一个长轮询,以便进行实时聊天。 我看了这篇文章 TopicRestController: private final Map<DeferredResult<String>, Long> chatRequests = new ConcurrentHashMap<DeferredResult<String>, Long>(); @RequestMappin
private final Map<DeferredResult<String>, Long> chatRequests =
new ConcurrentHashMap<DeferredResult<String>, Long>();
@RequestMapping(value="/{topicId}/updates" , method=RequestMethod.POST)
public @ResponseBody DeferredResult<String> isNewTopic(
@PathVariable Long topicId,
Model model, HttpSession session,
@RequestParam(required = true) String data) throws InterruptedException, CircularDefinitionException{
logger.info("New long polling request "+topicId);
final DeferredResult<String> result = new DeferredResult<String>();
this.chatRequests.put(result, topicId);
result.onCompletion(new Runnable() {
@Override
public void run() {
chatRequests.remove(result);
logger.info("Remove request from queue!");
}
});
Timestamp timestamp = new Timestamp(Long.valueOf(data)*1000L);
String updates = talkService.findNewTopicResponce(topicId,timestamp);
if (!updates.isEmpty()) {
result.setResult(updates);
}
return result;
}
@RequestMapping(value= "/{categoryId}" + "/addAnswer", method=POST)
public @ResponseBody Map respTopic(
@PathVariable Long categoryId,
@RequestParam String msg,
@RequestParam(required = false) String imageUrl,
@RequestParam(required = false) String title,
@RequestParam long talkId,
HttpServletRequest request
) throws CircularDefinitionException, MessagingException,TalkNotExistException{
........................
for (Entry<DeferredResult<String>, Long> entry : this.chatRequests.entrySet()){
if(entry.getValue().equals(talkId)){
entry.getKey().setResult(""+talkId);
}
}
}
私有最终映射请求=
新的ConcurrentHashMap();
@RequestMapping(value=“/{topicId}/updates”,method=RequestMethod.POST)
public@ResponseBody延迟结果为newtopic(
@路径变量长topicId,
模型,HttpSession会话,
@RequestParam(required=true)字符串数据)引发InterruptedException,CirculardDefinitionException{
logger.info(“新的长轮询请求”+topicId);
最终递延结果=新递延结果();
this.chatRequests.put(结果,topicId);
result.onCompletion(新的Runnable(){
@凌驾
公开募捐{
chatRequests.remove(结果);
info(“从队列中删除请求!”);
}
});
Timestamp Timestamp=新的时间戳(长值(数据)*1000L);
字符串更新=talkService.findnewtopiresponce(topicId,时间戳);
如果(!updates.isEmpty()){
result.setResult(更新);
}
返回结果;
}
@请求映射(value=“/{categoryId}”+“/addAnswer”,method=POST)
public@ResponseBody映射respTopic(
@路径变量长类别ID,
@RequestParam字符串消息,
@RequestParam(必需=false)字符串imageUrl,
@RequestParam(必需=false)字符串标题,
@RequestParam long talkId,
HttpServletRequest请求
)抛出CirculardDefinitionException、MessaginException、TalkNotExistException{
........................
for(条目:this.chatRequests.entrySet()){
如果(entry.getValue().equals(talkId)){
entry.getKey().setResult(“+talkId”);
}
}
}
现在的问题是:
当我调用“/{topicId}/updates”时,如果30秒后没有任何应答,服务器返回错误500,如果有人写了消息,服务器返回正确的消息,但服务器总是在30秒后响应,我需要服务器在有人写新消息时立即响应,而不是在超时过程中。我也遇到了同样的问题,我遇到了类似的问题: 基本上,您必须告诉Tomcat不要超时。您可以通过编辑
server.xml
Tomcat文件(在conf
目录中)以包含asyncTimeout
参数来实现这一点。这将告诉您的Tomcat在一分钟后超时:
使用值-1告诉Tomcat永不超时