javascript
tomcat 轮询_用Spring长轮询Tomcat
tomcat 輪詢
就像喜劇演員弗蘭基· 豪威爾 ( Frankie Howerd)所說的“噢,小姐小姐” ,但足夠多的英國影射和雙重誘惑,因為長輪詢Tomcat對隔壁的悶氣不是某種性的偏見,這是一種技術(或更像是一種hack)由于喬布斯(Steve Jobs)拒絕在iPhone和iPad上支持Adobe Flash Player而開發的 。 事實是,將Flash Player用作Web應用程序的一部分是一種很好的支持“ 發布和訂閱”范例的方法,因為它能夠滿足那些需要實時更新的情況,例如實時股票價格,新聞更新和更改。博彩賠率,而直接HTTP及其請求/回復范例是支持靜態頁面的一種好方法。 許多公司在開發使用Flash的應用程序方面投入了大量精力,以便為用戶提供實時數據。 當蘋果公司宣布iOS將不支持Adobe Flash時,如果沒有iPhone解決方案,它們就會變得干and無力,要重新進入移動市場,我想其中有很多都經過長時間的投票。
那么,什么是長期 投票 ? 嗯,這不是華沙的高個子,其想法是模仿“發布和訂閱”模式。 場景如下:
我懷疑Spring的Guy不太熱衷于“長期投票”一詞,因為他們更正式地將此技術稱為異步請求處理
在上面查看我的“長輪詢”或“ 異步請求處理”流程時,您可能會猜測服務器將發生什么。 每次您強迫服務器等待數據可用時,都會占用其一些寶貴資源。 如果您的網站很受歡迎并且負擔很重,那么等待更新消耗的資源數量會激增,因此服務器可能會用盡并崩潰。
在2月和3月,我寫了一系列有關Producer Consumer模式的博客,這似乎是進行長期投票的理想情況。 如果您尚未閱讀我的Producer Consumer模式博客,請在此處查看
在那種原始情況下,我說過“電視公司會向每個游戲發送記者,以將實時更新反饋到系統中,然后將其發送回演播室。 到達工作室后,更新將被放入隊列中,然后由電傳打字機顯示在屏幕上。”
隨著時代的變遷,電視公司希望用Web應用程序代替舊的Teletype,該應用程序可以實時顯示比賽更新。
在這種新情況下,電視公司總裁聘請了敏捷牛仔公司的朋友來整理更新。 為了使事情變得容易,他為他們提供了Message , Match和MatchReporter類的源代碼,這些類在新項目中可以重復使用。 Agile Cowboys的首席執行官為此聘用了一些新開發人員:負責前端JavaScript,JQuery,CSS和HTML專家以及負責Spring MVC Webapp的Java專家。
前端專家提供了以下JavaScript輪詢代碼:
var allow = true; var startUrl; var pollUrl; function Poll() { this.start = function start(start, poll) { startUrl = start; pollUrl = poll; if (request) { request.abort(); // abort any pending request } // fire off the request to MatchUpdateController var request = $.ajax({ url : startUrl, type : "get", }); // This is jQuery 1.8+ // callback handler that will be called on success request.done(function(reply) { console.log("Game on..." + reply); setInterval(function() { if (allow === true) { allow = false; getUpdate(); } }, 500); }); // callback handler that will be called on failure request.fail(function(jqXHR, textStatus, errorThrown) { // log the error to the console console.log("Start - the following error occured: " + textStatus, errorThrown); }); }; function getUpdate() { console.log("Okay let's go..."); if (request) { request.abort();? // abort any pending request } // fire off the request to MatchUpdateController var request = $.ajax({ url : pollUrl, type : "get", }); // This is jQuery 1.8+ // callback handler that will be called on success request.done(function(message) { console.log("Received a message"); var update = getUpdate(message); $(update).insertAfter('#first_row'); }); function getUpdate(message) { var update = "<div class='span-4? prepend-2'>" + "<p class='update'>Time:</p>" + "</div>" + "<div class='span-3 border'>" + "<p id='time' class='update'>" + message.matchTime + "</p>" + "</div>" + "<div class='span-13 append-2 last' id='update-div'>" + "<p id='message' class='update'>" + message.messageText + "</p>" + "</div>"; return update; }; // callback handler that will be called on failure request.fail(function(jqXHR, textStatus, errorThrown) { // log the error to the console console.log("Polling - the following error occured: " + textStatus, errorThrown); }); // callback handler that will be called regardless if the request failed or succeeded request.always(function() { allow = true; }); };? };名為Poll的類具有一個方法start() ,該方法帶有兩個參數。 瀏覽器使用第一個訂閱匹配更新數據供稿,而第二個是用于輪詢服務器以獲取更新的URL。 從JQuery ready(…)函數調用此代碼。
$(document).ready(function() {var startUrl = "matchupdate/subscribe";var pollUrl = "matchupdate/simple";var poll = new Poll();poll.start(startUrl,pollUrl);});調用start()方法時,它將向服務器發出Ajax請求以訂閱匹配更新。 當服務器以簡單的“ OK”答復時, request.done(…)處理程序通過使用帶有匿名函數作為參數的setInterval(…)啟動1/2秒計時器。 此函數使用一個簡單的標志“ allow ”,如果為true,則允許調用getUpdate()方法。 然后將allow標志設置為false,以確保不存在重入問題。
getUpdate(…)函數使用上述第二個URL參數對服務器進行另一個Ajax調用。 這次request.done(…)處理程序獲取匹配更新并將其轉換為HTML,并將其插入到“ first_row ” div之后,以將其顯示在屏幕上。
回到場景, 敏捷牛仔公司的首席執行官想打動他的新女友,于是他給她買了一輛保時捷911 。 現在他無法用自己的現金來支付,因為他的妻子會發現發生了什么事,所以他用電視公司交易中的一部分現金來支付。 這意味著他只能負擔一名應屆畢業生來編寫服務器端代碼。 這位畢業生可能沒有經驗,但是他確實重用了Message , Match和MatchReporter類以提供匹配更新。 請記住,將Queue和Match注入MatchReporter 。 調用MatchReporter.start()方法時,它將加載匹配項并讀取更新消息,并在其中檢查其時間戳,并在適當的時候將其添加到隊列中。 如果您想查看MatchReporter , Match等的代碼,請查看原始博客 。
然后,研究生將創建一個簡單的Spring比賽更新控制器
@Controller() public class SimpleMatchUpdateController { private static final Logger logger = LoggerFactory.getLogger(SimpleMatchUpdateController.class); @Autowired private SimpleMatchUpdateService updateService; @RequestMapping(value = "/matchupdate/subscribe" + "", method = RequestMethod.GET) @ResponseBody public String start() { updateService.subscribe(); return "OK"; } /** * Get hold of the latest match report - when it arrives But in the process * hold on to server resources */ @RequestMapping(value = "/matchupdate/simple", method = RequestMethod.GET) @ResponseBody public Message getUpdate() { Message message = updateService.getUpdate(); logger.info("Got the next update in a really bad way: {}", message.getMessageText()); return message; } }SimpleMatchUpdateController包含兩個非常簡單的方法。 第一個start()僅調用SimpleMatchUpdateService來訂閱比賽更新,而第二個getUpdate()向SimpleMatchUpdateService請求下一個比賽更新。 看到這一點,您可能會猜到所有工作都是由SimpleMatchUpdateService完成的。
@Service("SimpleService") public class SimpleMatchUpdateService { @Autowired @Qualifier("theQueue") private LinkedBlockingQueue<Message> queue; @Autowired @Qualifier("BillSkyes") private MatchReporter matchReporter; /** * Subscribe to a match */ public void subscribe() { matchReporter.start(); } /** * * Get hold of the latest match update */ public Message getUpdate() { try { Message message = queue.take(); return message; } catch (InterruptedException e) { throw new UpdateException("Cannot get latest update. " + e.getMessage(), e); } } }SimpleMatchUpdateService也包含兩個方法。 第一個, MatchReporter subscribe() ,告訴MatchReporter開始將更新放入隊列。 第二個getUpdate()從Queue刪除下一個更新,并將其作為JSON返回給瀏覽器以顯示。
到目前為止,一切都很好; 但是,在這種情況下,隊列是由LinkedBlockingQueue的實例實現的。 這意味著,如果瀏覽器發出請求時沒有可用的更新,則請求線程將阻塞queue.take()方法,從而占用寶貴的服務器資源。 可用更新時, queue.take()返回并將Message發送到瀏覽器。 對于沒有經驗的研究生培訓生來說,一切似乎都很好,并且代碼可以上線。 在接下來的周六,這是英超聯賽的開始(如果您在美國,則是足球比賽),也是體育日歷最繁忙的周末之一,并且有大量用戶希望獲得有關大型比賽的最新信息。 當然,服務器資源不足,無法處理負載并不斷崩潰。 電視公司的總裁對此不太滿意,因此召集了敏捷牛仔公司的首席執行官到他的辦公室。 他明確表示,如果不解決此問題,血液將流動。 Agile Cowboys的首席執行官意識到了自己的錯誤,并在與女友吵架后收回了保時捷。 然后,他通過電子郵件向Java / Spring顧問發送電子郵件,如果他要來修復代碼,則向他提供保時捷。 Spring顧問不能拒絕這樣的提議并接受。 這主要是因為他知道Servlet 3規范通過允許將ServletRequest置于異步模式來解決了這個問題。 這樣可以釋放服務器資源,但可以保持ServletResponse打開,從而允許其他一些第三方線程完成處理。 他還知道,Spring的家伙們在Spring3.2中想出了一種新技術,稱為“延遲結果”,該技術專為這些情況而設計。 同時,Agile Cowboys CEO的前女友仍對失去保時捷感到不安,向他的妻子發送電子郵件,告訴她有關丈夫的外遇的一切……
當這個博客變成達拉斯的一集時,我認為它的時代到此結束。 那么,代碼會及時修復嗎? Java / Spring顧問會花太多時間駕駛他的新保時捷嗎? 首席執行官會原諒他的女朋友嗎? 他的妻子會與他離婚嗎? 有關這些問題的答案,以及下次有關Spring的DeferredResult技術調整的更多信息, …
您可能已經注意到,示例代碼中還有另一個巨大的漏洞,那就是只能有一個訂戶。 由于這僅是示例代碼,而我在談論的是長時間輪詢,而不是實現發布和訂閱,因此問題出在“主題之外”。 我稍后可能會(也可能不會)對其進行修復。
該博客隨附的代碼可在Github上找到:https://github.com/roghughe/captaindebug/tree/master/long-poll
翻譯自: https://www.javacodegeeks.com/2013/08/long-polling-tomcat-with-spring.html
tomcat 輪詢
總結
以上是生活随笔為你收集整理的tomcat 轮询_用Spring长轮询Tomcat的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 24.98 万元起,AITO 问界新 M
- 下一篇: 怎样设置搜手机号就是微信号