2、异步HTTP编程
1、處理異步結果
? ? ? ?在內部,play框架是自下而上異步的。Play以異步、非阻塞方式處理每個請求。應用程序代碼應盡量避免阻塞控制器,這種阻塞操作的常見例子有JDBC調用、流式API、HTTP請求和長計算。因此應盡量通過保持控制器異步的方法使得應用進行擴展,使系統在負載下保持響應。就是說,對于控制器中的一些阻塞的操作,盡量使用異步的方式進行處理。
? ? ? ?Action中的處理要求盡可能的快,但是如果使用異步(Action默認處理請求就是異步的),那么可能會有這樣的問題,結果沒有計算出來,響應就已經返回了,這是怎么處理呢?Java 8中提供了類CompletionStage和CompletableFuture,這兩個類不具體介紹,只需要知道可以實現使得程序異步又可以獲取返回值,CompletionStage<result>最終將用result類型的值。返回CompletionStage<result>是一種編寫非阻塞代碼的技術。可以使用如下方式獲取:
? ? ? ? 實現異步處理、非阻塞編程的關鍵就在于CompletionStage,下邊介紹一下如何使用,第一種可以通過配合HttpExecutionContext使用,可以通過依賴項注入play提供的play.libs.concurrent.httpExecutionContext實例,如下:
? ? ? ?只是使用HttpExecutionContext和CompletableFuture還是使用的play默認的上下文執行器,還需要使用CustomExecutionContext和HttpExecution實現非阻塞編程,如下:
可以通過使用實現響應超時問題的處理:
2、流式HTTP響應
? ? ? ?為了保持單個連接的開放性以服務于多個HTTP請求和響應,服務器必須隨響應一起發送適當的內容長度的HTTP頭。對于響應一些簡單的文本結果,play可以自動識別并自動添加頭信息返回客戶端,但是對于一些復雜的內容,就需要開發者自己指定頭信息,play提供了類play.http.httpentity用來實現此功能,使用如下:? ?
? ? ? ?在這里就有一個問題,為了計算頭長度獲取頭信息,就需要將所有返回內容加載到內存,這里就可能存在問題:返回內容太大怎么辦?下邊先來一個返回結果的例子:? ? ?
? ? ? ?這里返回到客戶端一個流對象,由于需要判斷頭信息,而play不能在流中直接獲取頭信息,這是就需要將整個流添加到內存中進行分析。Play中對于此問題,早已提供實現,直接調用ok(new File(“文件路徑”))即可。
? ? ? ?上邊這種方式返回的文件大小必須是確定的,對于文件大小不能確定的、動態變化的就需要使用分塊傳輸編碼技術,使用如下:?
3、Comet套接字
? ? ? 使用分塊傳輸編碼技術實現Comet。Comet套接字是一個分塊的text/HTML響應,只包含<script>元素。對于每個塊,我們編寫一個包含JavaScript的<script>標記,該標記立即由Web瀏覽器執行。這樣我們就可以從服務器向Web瀏覽器實時發送事件:對于每條消息,將其包裝成一個調用javascript回調函數的<script>標記,并將其寫入分塊響應。
? ? ? ?因為ok().chunked利用akka流獲取流<bytestring>,所以我們可以發送一個元素流并對其進行轉換,以便在javascript方法中對每個元素進行轉義和包裝。Comet幫助程序自動執行Comet套接字,為瀏覽器兼容性推送初始空白緩沖區數據,并支持字符串和JSON消息。
下邊介紹幾個Comet的使用:
字符串流中使用Comet:? ??
Json流中使用Comet:
Iframe中使用Comet:
4、WebSockets(網絡套接字)
? ? ? ? WebSockets是基于允許雙向全雙工通信的協議從Web瀏覽器使用的套接字。只要服務器和客戶機之間有活動的WebSocket連接,客戶機就可以發送消息,服務器就可以隨時接收消息。WebSokets不能通過標準動作來處理。Play的WebSocket處理機制是圍繞Akka流構建的。WebSocket被建模為流,傳入的WebSocket消息被送入流中,流生成的消息被發送到客戶機。play提供了一些在WebSocket中構造WebSocket的工廠方法。
接下來介紹play中如何處理websocket。
? ? ? ?使用actors處理websocket,可以使用play實用程序ActorFlow將actorRef轉換為流。此實用程序接受一個函數,該函數將actorRef轉換為向akka.actor.props對象發送消息,該對象描述在接收WebSocket連接時play應創建的參與者:??
從客戶端接收到的任何消息都將發送給參與者,而由play提供的任何消息都將發送給客戶端,當websocket關閉時,actor將被停止,可以通過實現actors的 poststop方法來處理需要關閉的資源:
有時候希望拒絕WebSocket請求,例如,如果必須對用戶進行身份驗證才能連接到WebSocket,Play為此目的提供了AcceptorResult ?WebSocket ?Builder:
想要實現異步接收WebSocket,直接使用CompletionStage<WebSocket<A>>代替WebSocket<A>即可。
處理其他類型數據的請求:
還可以直接使用akka流處理WebSockets,如下:
WebSocket可以訪問請求頭(來自啟動WebSocket連接的HTTP請求),但是,它不能訪問請求主體,也不能訪問HTTP響應
發送hello之后丟棄輸入數據并關閉套接字:
輸入數據記錄到標準輸出,然后使用映射流發送回客戶機:
配置websocket的幀長度有兩種方式,在啟動應用是使用:
play.server.websocket.frame.maxLength 或者
Sbt -Dwebsocket.frame.maxLength=256k run
總結
以上是生活随笔為你收集整理的2、异步HTTP编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 天下3电脑配置要求(天下3 电脑配置)
- 下一篇: e3电脑主机配置(e3配置的电脑配置)