ai大模型流式输出------基于SSE协议的长连接实现
传统的http1.0哀求开发,已经满意了我们日常的web开发。一样平常哀求就像下图这样子,客服端发起一个哀求(触发),服务端做出一个相应(动作):
https://img2024.cnblogs.com/blog/704073/202412/704073-20241202111526759-1037869510.png
有时会有诸如及时革新,及时表现的场景,我们每每是客户端定时发起哀求,不断的尝试获取最新的数据。
但是每次哀求都会创建并释放一个新的连接,这样对于必要频繁哀求的场景,性能损耗太大,此外对于及时性相应的场景也很难评估轮询周期。轮询的周期短,很多查询结果其实并没有变化,增长了成本开销。轮询周期长,又不能及时的展示数据,周期值酿成了一个经验值,而且不同场景都必要不断的调整。这属实不够友好。
于是http1.1协议对此进行了扩展,允许长连接的存在。本日要介绍的SSE协议,就属于http1.1下的新协议。
SSE全称为 Sever-Sent Event
指服务器端变乱发送。当客户端哀求成功后,服务端会依次将变乱(其实就是相应信息),分多次发送到客户端。客户端只要接收变乱(相应信息),做出相应的处理即可。
就像下图的样子:
https://img2024.cnblogs.com/blog/704073/202412/704073-20241202111639038-282342583.png
比如K线增长图,及时热力图,各种增长曲线等等,都可以及时的,由后端主动将变乱推送到前端,不再必要前端每次创建一个新的连接来哀求。这种方式也称之为长连接。
除了SSE,像websocket 、TCP等都属于长连接的类型。依次连接可以多次交互。
SSE其实最初并不受器重,甚至很多人都不知道这个协议。如果是简单一点的话,通常直接多轮询几遍就办理题目了,如果是复杂一点的话,直接就使用websocket这样的重协议来处理了,功能也相对来说比较强大。但是自从交互大模型问世以后,大模型的流式对话每每能更高效的输出,这种流式输出的用户体验也更好。这种重要是偏庞大模型相应的交互模式,(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )反而使得SSE的优势又体现出来了。
下面我们看下如何在springboot中使用sse来开发:
由于springboot的封装,我们使用SSE开发变得异常简单,
核心思路是:
创建一个 SseEmitter 对象,返回给前端
这个SseEmitter类似于一个socket,我们只管向里边塞数据即可,
而前端在收到SseEmitter对象后,则只管从sseEmitter中取数据即可。(留意此处一样平常采用注册相应方式)
后端代码如下:
pom文件新增依靠:
1 <dependency>
2 <groupId>org.springframework.boot</groupId>
3 <artifactId>spring-boot-starter-web</artifactId>
4 </dependency>controller类:
1 package com.example.demo.learnsse; 23 import lombok.extern.slf4j.Slf4j; 4 import org.springframework.http.MediaType; 5 import org.springframework.web.bind.annotation.CrossOrigin; 6 import org.springframework.web.bind.annotation.GetMapping; 7 import org.springframework.web.bind.annotation.RequestParam; 8 import org.springframework.web.bind.annotation.RestController; 9 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;10 11 import java.io.IOException;12 import java.util.concurrent.TimeUnit;13 14 /**15* @discription16*/17 @Slf4j18 @RestController19 @CrossOrigin(origins = "*")20 public class SseController {21 22 23 @GetMapping(value = "/learn/sseChat" , produces = {MediaType.TEXT_EVENT_STREAM_VALUE})24 public SseEmitter chat(@RequestParam String name) throws IOException {25 SseEmitter sseEmitter = new SseEmitter(360000L);26 sseEmitter.onCompletion(() -> log.warn("sse complete!!!" + Thread.currentThread().getName()));27 sseEmitter.onError(throwable -> {28 log.warn("sse error" + Thread.currentThread().getName(), throwable);29 });30 sseEmitter.send("start");31 Runnable r = () -> {32 int i = 1;33 try {34 while (i
页:
[1]