Server-Sent Events(SSE)是一种基于 HTTP 的服务器推送技术,它允许服务器向客户端发送实时事件,而无需客户端不断地发起请求。SSE 是一种轻量级的实时通信技术,适合于实时更新数据、聊天应用、股票行情等场景。
本文将介绍如何在 Java 中使用 SSE 技术,包括 SSE 的基本原理、使用 SSE 的步骤、如何配置服务器和客户端等内容,同时提供示例代码供读者参考。
SSE 的基本原理
SSE 是一种基于 HTTP 的服务器推送技术,其基本原理如下:
- 客户端向服务器发送一个 HTTP 请求,请求的头部包含
Accept: text/event-stream
,表示客户端支持 SSE 技术。 - 服务器向客户端发送一个 HTTP 响应,响应的头部包含
Content-Type: text/event-stream
,表示服务器会发送 SSE 格式的数据。 - 服务器发送 SSE 格式的数据到客户端,每条数据以
data:
开头,以\n\n
结尾,其中\n\n
表示一条 SSE 数据的结束。 - 客户端通过 JavaScript 的
EventSource
对象监听服务器发送的 SSE 数据,每当接收到一条数据时,就会触发onmessage
事件,从而实现实时更新数据的功能。
使用 SSE 的步骤
使用 SSE 的步骤如下:
- 在客户端使用 JavaScript 的
EventSource
对象创建 SSE 连接。 - 在服务器端创建一个 SSE 服务,监听客户端的 SSE 连接。
- 当有数据需要推送时,服务器向 SSE 服务发送 SSE 格式的数据。
下面分别介绍这三个步骤的具体实现。
在客户端使用 EventSource
对象创建 SSE 连接
在客户端使用 EventSource
对象创建 SSE 连接的代码如下:
var source = new EventSource('/sse'); source.onmessage = function(event) { console.log(event.data); };
上述代码中,/sse
表示 SSE 服务的地址,source.onmessage
表示监听 SSE 数据的回调函数。
在服务器端创建 SSE 服务
在服务器端创建 SSE 服务的代码如下:
@WebServlet("/sse") public class SseServlet extends HttpServlet { private final List<AsyncContext> contexts = new CopyOnWriteArrayList<>(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/event-stream"); response.setCharacterEncoding("UTF-8"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); final AsyncContext asyncContext = request.startAsync(); asyncContext.setTimeout(0); contexts.add(asyncContext); } public void push(String data) throws IOException { for (AsyncContext asyncContext : contexts) { try (PrintWriter writer = asyncContext.getResponse().getWriter()) { writer.write("data: " + data + "\n\n"); writer.flush(); } catch (Exception ex) { contexts.remove(asyncContext); ex.printStackTrace(); } } } }
上述代码中,@WebServlet("/sse")
表示将该 Servlet 映射到 /sse
路径,contexts
表示所有 SSE 连接的上下文,doGet
方法表示客户端发起 SSE 连接时执行的方法,其中设置了响应头和超时时间,将上下文加入到 contexts
中。push
方法表示服务器向客户端推送 SSE 格式的数据,遍历 contexts
并向每个 SSE 连接发送数据。
向 SSE 服务推送数据
在服务器端,向 SSE 服务推送数据的代码如下:
SseServlet sseServlet = new SseServlet(); sseServlet.push("Hello, SSE!");
上述代码中,SseServlet
表示 SSE 服务的类,sseServlet.push
表示向 SSE 服务推送数据。
配置服务器和客户端
在使用 SSE 技术时,需要对服务器和客户端进行一些配置,具体如下:
服务器端配置
在服务器端,需要配置以下参数:
- 响应头:设置
Content-Type: text/event-stream
,表示服务器会发送 SSE 格式的数据。 - 超时时间:设置超时时间为 0,表示 SSE 连接不会超时关闭。
- 连接头:设置
Cache-Control: no-cache
和Connection: keep-alive
,表示不缓存数据,保持连接。
客户端配置
在客户端,需要配置以下参数:
EventSource
对象:使用EventSource
对象创建 SSE 连接。- 监听回调函数:监听
onmessage
事件,并在回调函数中处理 SSE 数据。
示例代码
下面是一个完整的使用 SSE 技术的示例代码:
@WebServlet("/sse") public class SseServlet extends HttpServlet { private final List<AsyncContext> contexts = new CopyOnWriteArrayList<>(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/event-stream"); response.setCharacterEncoding("UTF-8"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Connection", "keep-alive"); final AsyncContext asyncContext = request.startAsync(); asyncContext.setTimeout(0); contexts.add(asyncContext); } public void push(String data) throws IOException { for (AsyncContext asyncContext : contexts) { try (PrintWriter writer = asyncContext.getResponse().getWriter()) { writer.write("data: " + data + "\n\n"); writer.flush(); } catch (Exception ex) { contexts.remove(asyncContext); ex.printStackTrace(); } } } } public class SseDemo { public static void main(String[] args) throws IOException { SseServlet sseServlet = new SseServlet(); ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); executor.scheduleAtFixedRate(() -> { try { sseServlet.push("Hello, SSE!"); } catch (IOException ex) { ex.printStackTrace(); } }, 0, 1, TimeUnit.SECONDS); EventSource source = new EventSource("/sse"); source.onmessage = event -> { System.out.println(event.data); }; } }
上述代码中,SseServlet
表示 SSE 服务的类,doGet
方法表示客户端发起 SSE 连接时执行的方法,其中设置了响应头和超时时间,将上下文加入到 contexts
中。push
方法表示服务器向客户端推送 SSE 格式的数据,遍历 contexts
并向每个 SSE 连接发送数据。
SseDemo
表示客户端的类,其中使用 ScheduledExecutorService
定时向 SSE 服务推送数据,使用 EventSource
对象监听 SSE 数据的回调函数。
总结
本文介绍了如何在 Java 中使用 SSE 技术,包括 SSE 的基本原理、使用 SSE 的步骤、如何配置服务器和客户端等内容,同时提供了示例代码供读者参考。SSE 技术是一种轻量级的实时通信技术,适合于实时更新数据、聊天应用、股票行情等场景。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658a4583eb4cecbf2df7743d