共计 1266 个字符,预计需要花费 4 分钟才能阅读完成。
前言
之前实现服务端实时向客户端发送消息,Windward中只支持WebSocket,但是实现起来无论对于客户端还是服务端都有些过重了,但是今天,SSE来啦!实现和ChatGPT一样的流式输出不是梦!
正文开始
首先当然是函数定义,笔者这定义了2个函数,一个方法返回自动销毁SSE,一个则保留1小时
public class SSEFunction {
public static SseEjector sse(SseWindwardContext sseWindwardContext) {
SseEjector sseEjector = new SseEjector(sseWindwardContext);
sseEjector.send(SseEventSource.builder().data("hi! "));
return sseEjector; // 默认方法结束就终止
}
public static SseEjector keepAliveSse(SseWindwardContext sseWindwardContext) {
SseEjector sseEjector = new SseEjector(sseWindwardContext);
sseEjector.send(SseEventSource.builder().data("hi! "));
return sseEjector.keepAlive(3600L); // 保活1小时 sseEjector在此期间内仍能发送消息
}
}
如果我们想实现ChatGPT一样的流式效果,只需要使用第一种写法,多次发送数据包
public static SseEjector sse(SseWindwardContext sseWindwardContext) {
SseEjector sseEjector = new SseEjector(sseWindwardContext);
for (int i = 0; i < 10; i++) {
sseEjector.send(SseEventSource.builder().data("hi! " + i));
}
return sseEjector; // 方法结束我们就直接关闭SSE 再次提问再调用该接口
}
这样我们的客户端会收到流式的响应,直接渲染就OK了
最后
定义好函数,不注册自然是不行的,一般而言,如果我们不需要传递复杂参数,客户端可以依托浏览器内置的SSE支持,使用GET方法注册SSE
windward.sse("/sse", SSEFunction::sse).sse("/alive-sse", SSEFunction::keepAliveSse);
当然,如果需要复杂传参,浏览器内置的GET方法SSE就不行了,这时候我们可以注册为POST
windward
.sse(HttpMethod.POST, "/sse", SSEFunction::sse)
.sse(HttpMethod.POST, "/sse", SSEFunction::keepAliveSse);
客户端可以使用开源扩展库,例如 fetch-event-source,实现复杂传参
正文完
1.5.1-RELEASE已经发布!正式支持该特性!