问题
I have a Spring MVC 3.2 application and i need to add a Long Polling to this Web service for a real time chat. I followed this article Spring MVC 3.2 Preview: Chat Sample.
TopicRestController:
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);
}
}
}
Now the problem is:
when i call "/{topicId}/updates" if there is not any answer after 30 second the server return Error 500, if someone wrote a message the server return the correct message but the server always responds after 30 seconds, i need the server responds immediately when someone writes a new message and not at the timeout process.
回答1:
I just had the same problem, and I came across this similar question: Tomcat 7 server error after 10 seconds when long polling
Basically, you have to tell Tomcat not to timeout. You do this by editing your server.xml
Tomcat file (in your conf
directory) to include an asyncTimeout
parameter. This would tell your Tomcat to timeout after a minute:
<Connector port="8080" protocol="HTTP/1.1" asyncTimeout="60000" connectionTimeout="20000" redirectPort="8443" />
Using a value of -1 tells Tomcat to never timeout.
来源:https://stackoverflow.com/questions/31683328/spring-long-polling-with-deferredresult