SpringBoot+WebFlux透過流式響應實現類似ChatGPT的打字機效果

juyss發表於2024-06-12

突然間想用Java實現一下像ChatGPT一樣的打字機輸出效果,但是網上搜了相關教程感覺都不夠滿意。
這裡貼一下自己的實現,為中文網際網路做一點小小的貢獻

最主要的一點就是響應的Content-Type設定為MediaType.TEXT_EVENT_STREAM_VALUE


實現效果如下

然後貼一下自己的程式碼吧
思路就是把從檔案讀取的每一個字元重新合併為一個陣列,當然,也可以替換成從其他地方獲得的字元
透過fromArray()方法將包裝好的字元陣列一個個按順序返回,透過delayElements()指定一個延遲時間,從而實現類似ChatGPT的打字機效果

我這裡是從resources/static/test.txt讀取檔案,透過轉換後得到Character[]陣列,一定要是包裝類陣列,基本資料型別不行。

感覺程式碼不夠優雅,轉換個字元竟然這麼麻煩,希望能有大佬指點。

import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.time.Duration;

/**
 * @author Juyss
 * @version 1.0
 * @description: TODO
 * @date 2024/6/11 20:52
 */
@RestController
@RequestMapping("/chat")
public class ChatController {

    @GetMapping(value = "/webflux",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<Character> chatWebFlux(@RequestParam int delay) throws IOException {
        //讀取檔案作為字串陣列資料來源
        DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource("classpath:static/test.txt");
        byte[] byteArray = resource.getContentAsByteArray();
        String s = new String(byteArray);
        char[] charArray = s.toCharArray();
        //將基本資料型別的字元陣列包裝為引用資料型別
        Character[] characters = String.valueOf(charArray).chars().mapToObj(b -> (char) b).toArray(Character[]::new);
        //透過fromArray()方法將包裝好的字元陣列一個個按順序返回,透過delayElements()指定一個延遲時間,從而實現類似ChatGPT的打字機效果
        return Flux.fromArray(characters).delayElements(Duration.ofMillis(delay));
    }
}

相關文章