.xhr长轮询_使用Spring 3.2的DeferredResult进行长轮询

.xhr长轮询

在我们的最后一集中 , Agile Cowboys Inc.的首席执行官刚刚雇用了Java / Spring顾问,方法是为他提供最初为女友购买的保时捷。 这位首席执行官的女友因失去保时捷而感到不安,已将其婚外恋告诉了他的妻子。 他的妻子在分拆了CEO的套房后已申请离婚。 同时,首席执行官在办公室实施了新的“休闲”着装要求,而Java / Spring顾问刚从他的保时捷换来的回程中,正坐在办公桌旁准备修理电视公司的软件……如果不这样做的话对您没有任何意义,然后看一下使用Spring的Long Polling Tomcat 。

Java / Spring顾问必须在下一个大型游戏之前解决电视公司的服务器资源问题,他知道他可以通过使用在Tomcat 7 1上实现的Servlet 3规范实现Spring的Deferred Result技术来解决此问题。

Java / Spring顾问要做的第一件事是检查 项目的pom.xml文件。 对于异步Servlet 3项目,您必须包括以下依赖项:


        javax.servlet
        javax.servlet-api
        3.0.1
        provided
    

接下来,您必须告诉Tomcat Spring DispatcherServlet支持Servlet 3异步通信。 这是通过将以下行添加到web.xml

true

完整的DispatcherServlet配置为:


 appServlet
 org.springframework.web.servlet.DispatcherServlet
 
  contextConfigLocation
  /WEB-INF/spring/appServlet/servlet-context.xml
 
 1
        true
    

整理完项目配置后,Java / Spring ConsultantSwift进入了控制器代码。 他用新的DeferredMatchUpdateController替换了研究生培训生的SimpleMatchUpdateController

@Controller() 
public class DeferredMatchUpdateController { 

  @Autowired 
  private DeferredResultService updateService; 

  @RequestMapping(value = "/matchupdate/begin" + "", method = RequestMethod.GET) 
  @ResponseBody 
  public String start() { 
    updateService.subscribe(); 
    return "OK"; 
  } 

  @RequestMapping("/matchupdate/deferred") 
  @ResponseBody 
  public DeferredResult getUpdate() { 

    final DeferredResult result = new DeferredResult(); 
    updateService.getUpdate(result); 
    return result; 
  } 
}

新的DeferredMatchUpdateController非常简单。 与SimpleMatchUpdateController一样,它包含两个方法: start()getUpdate() ,它们的功能与简单方法完全相同。 这使该控制器成为SimpleMatchUpdateController的插件替代品。 最大的不同是, getUpdate()方法创建Spring的DeferredResult的实例,该实例在将其返回给Spring之前传递给新的DeferredResultService 。 然后,Spring停放HTTP请求,使其挂起,直到DeferredResult对象具有一些要返回到浏览器的数据为止。

@Service("DeferredService") 
public class DeferredResultService implements Runnable { 

  private static final Logger logger = LoggerFactory.getLogger(DeferredResultService.class); 

  private final BlockingQueue> resultQueue = new LinkedBlockingQueue<>(); 

  private Thread thread; 

  private volatile boolean start = true; 

  @Autowired 
  @Qualifier("theQueue") 
  private LinkedBlockingQueue queue; 

  @Autowired 
  @Qualifier("BillSkyes") 
  private MatchReporter matchReporter; 

  public void subscribe() { 
    logger.info("Starting server"); 
    matchReporter.start(); 
    startThread(); 
  } 

  private void startThread() { 

    if (start) { 
      synchronized (this) { 
        if (start) { 
          start = false; 
          thread = new Thread(this, "Studio Teletype"); 
          thread.start(); 
        } 
      } 
    } 
  } 

  @Override 
  public void run() { 

    while (true) { 
      try { 

        DeferredResult result = resultQueue.take(); 
        Message message = queue.take(); 

        result.setResult(message); 

      } catch (InterruptedException e) { 
        throw new UpdateException("Cannot get latest update. " + e.getMessage(), e); 
      } 
    } 
  } 

  public void getUpdate(DeferredResult result) { 
    resultQueue.add(result); 
  } 

}

同样,像其对应的SimpleMatchUpdateServiceDeferredResultService包含两个方法: subscribe()getUpdate()

与处理getUpdate(...)它的作用是为新创建的添加DeferredResult对象到LinkedBlockingQueueresultQueue ,以便它可以在以后当比赛更新可用来处理。

真正的工作是通过subscribe()方法完成的。 首先,此方法启动matchReporter ,它在适当的时候将匹配更新输入到自动连接的queue实例中。 然后,它调用私有的startThread()方法来启动工作线程。 该操作仅启动一次,并使用双重检查锁定来确保高效且没有问题。

线程的run()方法首先无限循环,从resultQueue获取DeferredResult对象(如果有),然后从Message对象中获取代表来自更新queue的匹配更新的Message对象(如果有)。 然后,使用message对象作为参数调用DeferredResultsetResult(...) 。 Spring现在将接管工作,原始的长轮询请求将完成,并且数据将延迟地返回给浏览器。

请注意,在此示例代码中, run()方法包含while(true)循环。 尽管此技术简化了示例代码,但在生产代码方面并不是一个好主意。 使用不受控制的不受控制的线程的问题之一是它们会阻止Tomcat正确关闭,并且您通常必须使用良好的Unix kill命令来停止服务器。 在生产代码中,最好包含代码以正常关闭此类工作线程。

经过数小时的辛苦工作后,Java / Spring顾问将其代码推广到生活中,拿起保时捷的钥匙,然后旋转一下。 下个星期六,使用Spring的DeferredResult ,服务器可以很好地应对:用户很高兴,电视公司的总裁很高兴, Agile Cowboys Inc的首席执行官很高兴,尽管他一直怀疑自己付给顾问的钱太多了,但是,这只是金钱。

1在撰写此博客时,我使用的是Tomcat 7.0.42版

该博客随附的代码可在Github上找到: https : //github.com/roghughe/captaindebug/tree/master/long-poll

参考: Captain Debug博客博客中来自JCG合作伙伴 Roger Hughes的Spring 3.2的DeferredResult长轮询 。

翻译自: https://www.javacodegeeks.com/2013/09/long-polling-with-spring-3-2s-deferredresult.html

.xhr长轮询

你可能感兴趣的:(java,spring,js,spring,boot,vue,ViewUI)