<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          spring-webflux真 · 流式編程

          共 4296字,需瀏覽 9分鐘

           ·

          2021-07-31 01:57

          前言

          今天我們來看下webflux比較奇特的操作。當然這些操作,在我們以前的web應(yīng)用中很難實現(xiàn)的,至少實現(xiàn)起來并不容易。

          webflux

          下面是一個webflux流式編程的典型樣例,簡單來說就是,前端請求一次,收到請求后會源源不斷地向前端傳輸數(shù)據(jù)。

          這感覺就像我們的水管一樣,前端發(fā)送一個開啟傳輸?shù)闹噶?,然后后端就開始像放水一樣像前端傳輸數(shù)據(jù)了。

          接口配置

          下面是接口的實現(xiàn),這里和我們前面分享的接口有所不同,這里響應(yīng)數(shù)據(jù)傳輸?shù)娜萜饔玫氖?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">Flux,之前都用的是Mono。關(guān)于兩者的區(qū)別,根據(jù)我查到的資料,Mono一般用于返回01個元素的異步序列Publisher,也就和我們傳統(tǒng)的MVC很像;而Flux時返回0或者N個元素組成的PublisherPublisher的作用類似于消息分發(fā)中心這樣的角色,核心方法是subscribe

           public Mono<ServerResponse> sendTimePerSec(ServerRequest serverRequest) {
                  return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(  // 1
                          Flux.interval(Duration.ofSeconds(1)).   // 2
                                  map(l -> new SimpleDateFormat("HH:mm:ss").format(new Date())),
                          String.class);
              }

          這個接口的作用是,間隔一秒向前端發(fā)送當前時間,時間格式HH:mm:ss。

          這里需要注意的是,這里的請求頭設(shè)置的是TEXT_EVENT_STREAM,這種響應(yīng)頭和之前的區(qū)別后面我們會演示,這里大家留意下就行。

          interval是一個延遲回調(diào)方法,當達到指定的延遲時間period,方法返回值是循環(huán)的次數(shù),從0開始。下面是官方文檔給出的interval方法的示意圖,還是比較形象的

          map方法應(yīng)該不需要過多說明吧,用過lambda表達式的小伙伴,應(yīng)該很熟悉,在這里它的作用也是做類型轉(zhuǎn)換,這里的寫法是lambda的寫法,完整寫法是這樣的:

          .map(new Function<Long, String>() {
                              @Override
                              public String apply(Long l) {
                                  System.out.println(l);
                                  return new SimpleDateFormat("HH:mm:ss").format(new Date());
                              }
                          })

          路由配置

          這里是設(shè)置我們接口的路由信息,包括請求方式、地址、處理器等。

          @Bean
              public RouterFunction<ServerResponse> routSayHi(HiHandler handler) {
                  return RouterFunctions
                          .route(RequestPredicates.GET("webflux/hi")
                                  .and(RequestPredicates.accept(MediaType.ALL)), handler::sayHi)
                          .andRoute(RequestPredicates.GET("/webflux/test")
                                  .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::sendTimePerSec);
              }

          測試運行

          訪問我們的接口,你會發(fā)現(xiàn),雖然前端只訪問了一次,數(shù)據(jù)一直在持續(xù)輸出,當然如果你點擊瀏覽器上面的X,就相當于本次請求結(jié)束,數(shù)據(jù)也就不再傳輸了。

          而且后端也在持續(xù)輸出,就像水管一樣,水一直在流動。

          另外根據(jù)我們運行結(jié)果來看,我們發(fā)現(xiàn)Flux類型的響應(yīng)數(shù)據(jù)和之前的響應(yīng)類型(Mono)相比是不一樣的,在Flux的響應(yīng)數(shù)據(jù)中,我們會發(fā)現(xiàn)接口的響應(yīng)頭變成了text/event-stream;charset=UTF-8,也就是我們前面執(zhí)行的響應(yīng)頭,而且多了一個請求頭transfer-encoding: chunked,這個請求頭表明我們的響應(yīng)數(shù)據(jù)長度是不確定的,據(jù)說這種方式占用的資源更少,可以讓數(shù)據(jù)一塊一塊輸出。

          關(guān)于兩者區(qū)別,我暫時還不清楚,但是如果把Mono的響應(yīng)體改成TEXT_EVENT_STREAM,返回結(jié)果依然正常,但是如果把Flux的響應(yīng)類型改成APPLICATION_JSON,雖然頁面依然會持續(xù)有數(shù)據(jù)輸出,但是看起來比剛才奇怪了:

          好了, 關(guān)于webflux的流式編程就先演示到這里,后面我們看情況繼續(xù)深入。

          總結(jié)

          經(jīng)過這幾天的摸索和學(xué)習,我慢慢對webflux有了更深入的了解和認識,但是同時也發(fā)現(xiàn)webflux的相關(guān)只是真的是太多了,而且是越學(xué)習感覺不知道的東西越多(知識的悖論,知識的詛咒),所以也只能說自己以前想的太天真了,竟然還想通過三五天的時間就學(xué)會webflux

          另外,我也發(fā)現(xiàn)目前市面上關(guān)于webflux的相關(guān)知識、書籍和博客都比較少,而且大部分都不夠系統(tǒng),所以關(guān)于webflux的學(xué)習,我已經(jīng)做好了持久戰(zhàn)的準備,以后應(yīng)該不會每天更新,這樣確實比較容易上頭,另一方面,如果積累的知識點不夠的話,很容易言之無物,所以綜合起來看,拉長戰(zhàn)線會是一個比較合理的選擇。

          最后,給各位i小伙伴一個建議,在學(xué)習的時候,一定要定期去復(fù)習,不然之前學(xué)習的知識點比較容易忘記。這兩天我在用線程池的時候,還專門去翻了之前的博客,因為好多東西又忘了

          - END -


          瀏覽 100
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  高清无码在线视频观看 | 7799视频 | ww视频免费观看 | 又污又黄的网站 | 偷偷操不一样的久久 |