后端:
private static SseEmitter sendEventStreamPost(String url, String jsonData){
SseEmitter emitter = new SseEmitter();
Mono.fromCallable(() -> {
WebClient.create(url)
.post()
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.TEXT_EVENT_STREAM)
.body(BodyInserters.fromValue(jsonData))
.retrieve()
.bodyToFlux(byte[].class)
.doOnNext(data -> {
try {
emitter.send(data);
} catch (IOException e) {
log.error("Event Stream Exception:" + e);
}
})
.doOnError(error -> {
log.error("Event Stream Error:" + error);
})
.doOnComplete(() -> {
emitter.complete();
})
.subscribe();
return emitter;
})
.subscribeOn(Schedulers.boundedElastic())
.subscribe();
return emitter;
}
其中曾踩了一些坑:
1.原本是bodyToFlux(String.class),结果没有返回也没有报错,排查了许久,最终改成bodyToFlux(byte[].class)
2.原本未使用Mono.fromCallable进行异步请求,结果其实是一次获取到完整的流再给前端,与长连接实时输出信息相悖。实际应该把SseEmitter返回给前端,异步调用接口对SseEmitter进行写入并且在完成后emitter.complete()关闭流。
前端,vue框架:文章来源:https://www.toymoban.com/news/detail-841628.html
import { fetchEventSource } from '@microsoft/fetch-event-source'
methods: {
test() {
var data = {
sendContent: "你好,你能帮我做些什么"
}
if ('EventSource' in window) {
const url = 'http://xxx/api/help/chat/sendMsgStream'
var _this = this
fetchEventSource(url, {
method: 'POST',
headers: {
"Content-Type": 'application/json',
"Accept": "*/*"
},
body: JSON.stringify(data),
onmessage(event) {
console.info("event.data:", event.data);
const eventData = event.data
_this.msg += eventData
},
onerror(err) {
console.log('err:',err)
}
})
} else {
console.log("error")
}
}
}
其中msg绑定的是聊天窗口的机器人答复,目前前端代码并不完善,在eroor时并未断开连接,等解决了再编辑文章来源地址https://www.toymoban.com/news/detail-841628.html
到了这里,关于获取第三方接口的EventStream返回给前端,SpringBoot+Vue+WebFlux+SseEmitter的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!