SpringBoot向前端实时输出日志
传统的HTTP请求只能由客户端发起,而服务端要想给客户端源源不断的发送数据,必须由客户端不断的向服务端发起请求,Ajax轮询,这种方式显然更加浪费开销。
WebSocket是HTML5提供的一种在单个TCP连接进行全双工的通信协议。
浏览器和服务器只需要一个握手动作,就形成了一条快速通道,两者之间即可方便的数据持续互传,直到客户端或者服务器中的某一方主动关闭连接。
使用Linux的tail -f读取服务器日志,在前端实时展示。
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
注册WebSocket服务
@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
编写Controller
@ServerEndpoint("/log") @RestController public class WebSocketController { private Process process; private InputStream inputStream; /** * 新的WebSocket请求开启 */ @OnOpen public void onOpen(Session session) { try { process = Runtime.getRuntime().exec("tail -f /logs/es-sync/es-sync.log"); inputStream = process.getInputStream(); TailfLogThread thread = new TailfLogThread(inputStream, session); thread.start(); } catch (IOException e) { e.printStackTrace(); } } /** * WebSocket请求关闭 */ @OnClose public void onClose() { try { if(inputStream != null) inputStream.close(); } catch (Exception e) { e.printStackTrace(); } if(process != null) process.destroy(); } @OnError public void onError(Throwable thr) { thr.printStackTrace(); } }
public class TailfLogThread extends Thread { private BufferedReader reader; private Session session; public TailfLogThread(InputStream in, Session session) { this.reader = new BufferedReader(new InputStreamReader(in)); this.session = session; } @Override public void run() { String line; try { while((line = reader.readLine()) != null) { // 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行 session.getBasicRemote().sendText(line + "<br>"); } } catch (IOException e) { e.printStackTrace(); } } }
前端HTML
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>tail log</title> <script src="http://cdn.bootcss.com/jquery/2.1.4/jquery.js"></script> </head> <body> <div id="log-container" style="height: 650px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;"> <div> </div> </div> </body> <script> $(document).ready(function() { var websocket = new WebSocket(ws://localhost:8080/log); websocket.onmessage = function(event) { $("#log-container div").append(event.data); $("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height()); }; }); </script> </body> </html>
启动项目,访问正常接口,有了!