我正在使用 EventSourcePolyfill
"@types/event-source-polyfill": "^1.0.1"
作为 sse 客户端,这是我的客户端打字稿代码,如下所示:
import { IChatAsk } from '../../models/chat/ChatAsk';
import { EventSourcePolyfill } from 'event-source-polyfill';
import { v4 as uuid } from 'uuid';
export function doSseChatAsk(params: IChatAsk, onSseMessage: (msg: string) => void,) {
let eventSource: EventSourcePolyfill;
const accessToken = localStorage.getItem("x-access-token");
// https://stackoverflow.com/questions/6623232/eventsource-and-basic-http-authentication
eventSource = new EventSourcePolyfill('/ai/stream/chat/ask?question=' + params.prompt, {
headers: {
'x-access-token': accessToken ?? "",
'x-request-id': uuid(),
}
});
eventSource.onopen = () => {
console.log("onopen....")
}
eventSource.onerror = (error) => {
console.log("onerror",error)
if(eventSource){
eventSource.close();
}
}
eventSource.onmessage = e => {
onSseMessage(e.data);
};
eventSource.addEventListener('complete', () => {
console.log('Transfer of data is complete');
});
eventSource.addEventListener('onclose', () => {
console.log('Transfer of data is complete');
});
}
我想知道是否有可能捕捉到完整的事件?现在发现在后端代码中调用emitter complete时,前端没有触发complete事件,是否可以捕获?这是我的后端 java 代码:
public static void okHttpEvent(SseEmitter emitter, String prompt, String openAiKey) {
Request request = new Request.Builder()
.url("https://chat.example.top/v1/chat/stream/completions?q=" + prompt)
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@NonNull
@Override
public Response intercept(@NonNull Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("Authorization", "Bearer " + openAiKey)
.header("Accept", MediaType.TEXT_EVENT_STREAM.toString())
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
})
.connectTimeout(3, TimeUnit.MINUTES)
.readTimeout(3, TimeUnit.MINUTES)
.build();
RealEventSource realEventSource = new RealEventSource(request, new EventSourceListener() {
@Override
public void onOpen(EventSource eventSource, Response response) {
}
@Override
public void onEvent(EventSource eventSource, String id, String type, String data) {
try {
emitter.send(data);
} catch (IOException e) {
emitter.completeWithError(e);
}
}
@Override
public void onClosed(EventSource eventSource) {
emitter.complete();
}
@Override
public void onFailure(EventSource eventSource, Throwable t, Response response) {
emitter.completeWithError(t);
}
});
realEventSource.connect(okHttpClient);
}
我跟踪后端代码并确保它在后端调用 emitter.complete 函数。