文章目錄
- 1、推送-SseEmitter
- 2、接收-EventSourceListener
SSE(Server-Sent Events,服務器推送事件)是一種基于HTTP的服務器向客戶端實時推送數據的技術標準。
1、推送-SseEmitter
SseEmitter用于實現服務器向客戶端單向、長連接的實時數據推送。
比如用于大模型機器人回答推送給前端(逐字逐詞顯示)
作為服務端,使用.send()
方法發送數據,.complete()
方法完成并結束連接,簡單示例:
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;@GetMapping("/test")
public SseEmitter test() {SseEmitter emitter = new SseEmitter(30_000L); // 超時時間設為30秒ExecutorService executor = Executors.newSingleThreadExecutor();// 模擬異步數據推送executor.execute(() -> {try {for (int i = 0; i < 10; i++) {emitter.send("Event " + i); // 發送數據Thread.sleep(1000);}emitter.complete(); // 正常結束} catch (Exception e) {emitter.completeWithError(e); // 異常終止}});return emitter;
}
2、接收-EventSourceListener
可以使用js接收sse事件流,當然如果是后端接口,也可以用java接收,使用EventSourceListener
處理從服務器端通過 SSE(Server-Sent Events)推送的事件流。
在EventSourceListener中覆寫onEvent方法,onEvent方法在每次服務器推送新事件時調用;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;public void listenTest(String url, String param){OkHttpClient client = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.MINUTES).readTimeout(5, TimeUnit.MINUTES).build();RequestBody formBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), param);Request request = new Request.Builder().post(formBody).url(url).build();EventSourceListener listener = new EventSourceListener() {// 連接建立時觸發,非必須@Overridepublic void onOpen(EventSource eventSource, Response response) {System.out.println("SSE連接已建立");System.out.println("響應頭: " + response.headers());}// 收到消息時觸發@Overridepublic void onEvent(EventSource eventSource, String id, String type, String data) {//在這里對推送過來的數據做解析和處理System.out.printf("收到事件: id=%s, type=%s, data=%s\n", id, type, data);}// 連接關閉時觸發@Overridepublic void onClosed(EventSource eventSource) {System.out.println("SSE連接已關閉");}// 發生錯誤時觸發(包括網絡錯誤和協議錯誤)@Overridepublic void onFailure(EventSource eventSource, Throwable t, Response response) {System.err.println("SSE錯誤: " + t.getMessage());if (response != null) {System.err.println("錯誤響應碼: " + response.code());}eventSource.cancel();//關閉連接}}EventSource.Factory factory = EventSources.createFactory(client);factory.newEventSource(request, listener);
}