使用模型生成问题答案时,由于是一个一个字或词生成的,前端等待后台所有答案生成后再返回体验极其不好,使用SseEmitter建立长链接
java代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@RestController
public class StreamController {
@GetMapping("/stream")
public SseEmitter streamData() {
SseEmitter emitter = new SseEmitter();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
try {
String data = "Hello word!!!!"; //文本
for (int i = 0; i < data.length(); i++) {
emitter.send(String.valueOf(data.charAt(i)));
Thread.sleep(1000); // 等待一秒
}
emitter.complete();
} catch (IOException | InterruptedException e) {
emitter.completeWithError(e);
}
});
executor.shutdown();
return emitter;
}
}
vue代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stream Data</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>Received Data: {{ receivedMessage }}</h1>
</div>
<script>
new Vue({
el: '#app',
data: {
receivedMessage: ''
},
mounted() {
this.connect();
},
methods: {
connect() {
const eventSource = new EventSource('http://localhost:8080/stream');
eventSource.onmessage = event => {
this.receivedMessage += event.data;
};
eventSource.onerror = error => {
console.error('EventSource failed:', error);
eventSource.close();
};
}
}
});
</script>
</body>
</html>
在后端,我们使用SseEmitter
来发送SSE消息。我们创建一个线程来模拟发送数据,每隔一秒发送一个字符。在前端,我们使用Vue.js创建一个简单的应用程序来监听这些SSE消息。每当接收到一个字符时,它就会被添加到receivedMessage
中,并立即显示在页面上。
这样,你就可以看到后端每秒发送一个字符,前端也会实时更新显示这些字符。