本文介绍了带有DeferredResult的春季长轮询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Spring MVC 3.2应用程序,我需要向此Web服务添加一个Long Polling才能进行实时聊天.我关注了这篇文章 Spring MVC 3.2预览版:聊天示例.

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:

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);
                            }
                        }

    }

现在的问题是:

当我呼叫"/{topicId}/updates"时,如果在30秒后没有任何应答,服务器将返回错误500,如果有人写了一条消息,服务器将返回正确的消息,但服务器始终在30秒后响应,我需要服务器在有人写新消息时而不是在超时过程中立即做出响应.

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.

推荐答案

我遇到了同样的问题,并且遇到了类似的问题:

I just had the same problem, and I came across this similar question: Tomcat 7 server error after 10 seconds when long polling

基本上,您必须告诉Tomcat不要超时.为此,您可以编辑server.xml Tomcat文件(在conf目录中)以包含asyncTimeout参数.这会告诉您的Tomcat一分钟后超时:

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" />

使用值-1告诉Tomcat永不超时.

Using a value of -1 tells Tomcat to never timeout.

这篇关于带有DeferredResult的春季长轮询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 05:05