javascript
使用Spring 3.2的DeferredResult进行长轮询
在我們的最后一集中 , 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項目,必須包括以下依賴項:
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency>接下來,您必須告訴Tomcat Spring DispatcherServlet支持Servlet 3異步通信。 這是通過將以下行添加到web.xml :
<async-supported>true</async-supported>完整的DispatcherServlet配置為:
<servlet><servlet-name>appServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value></init-param><load-on-startup>1</load-on-startup><async-supported>true</async-supported></servlet>整理完項目配置后,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<Message> getUpdate() { final DeferredResult<Message> result = new DeferredResult<Message>(); 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<DeferredResult<Message>> resultQueue = new LinkedBlockingQueue<>(); private Thread thread; private volatile boolean start = true; @Autowired @Qualifier("theQueue") private LinkedBlockingQueue<Message> 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<Message> 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<Message> result) { resultQueue.add(result); } }同樣,像其對應的SimpleMatchUpdateService , DeferredResultService包含兩個方法: subscribe()和getUpdate()
與處理getUpdate(...)它的作用是為新創建的添加DeferredResult對象到LinkedBlockingQueue叫resultQueue ,以便它可以在以后當比賽更新可用來處理。
實際工作是通過subscribe()方法完成的。 首先,此方法啟動matchReporter ,它在適當的時候將匹配更新輸入到自動裝配的queue實例中。 然后,它調用私有的startThread()方法來啟動工作線程。 該操作僅啟動一次,并使用雙重檢查鎖定來確保高效且沒有問題。
線程的run()方法首先無限循環,從resultQueue (如果有)中獲取DeferredResult對象,然后是Message對象,該對象代表來自update queue的匹配更新(如果有)。 然后,使用message對象作為參數調用DeferredResult的setResult(...) 。 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
翻譯自: https://www.javacodegeeks.com/2013/09/long-polling-with-spring-3-2s-deferredresult.html
總結
以上是生活随笔為你收集整理的使用Spring 3.2的DeferredResult进行长轮询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过快速Java和文件序列化加快速度
- 下一篇: linux系统pdf怎么转换成word(