传统的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>
启动项目,访问正常接口,有了!