背景
服务发生异常时,每次都登录服务器查看日志有些费时费力。
WebSocket
WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。
它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
示例(SpringBoot)
引入 websocket 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
注入 websocket 配置
package cn.caojiantao.tutorials.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
编写 socket handle 处理器
package cn.caojiantao.tutorials.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
/**
* websocket 实现日志实时推送
*/
@ServerEndpoint("/logs")
@Component
public class LogWebSocketHandle {
@OnOpen
public void onOpen(Session session) {
// 建议开启线程处理,避免 open 阻塞
try {
InputStream is = Runtime.getRuntime().exec("tail -f test.log").getInputStream();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
while ((line = reader.readLine()) != null) {
if (session.isOpen()) {
session.getBasicRemote().sendText(line + "\r\n");
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@OnMessage
public void onMessage(String message) {
System.out.println("message is arrived: " + message);
}
}
注意:websocket 默认多实例,内部注入 bean 可以采取全局 ApplicationContext 获取。
前端建立 websocket 连接
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket 实时日志</title>
</head>
<body>
<div class="content" style="height: 200px;"></div>
<script>
let ws = new WebSocket("ws://127.0.0.1:8088/logs");
ws.onopen = function() {
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
let content = document.getElementsByClassName('content')[0];
content.innerText = content.innerText + evt.data.replace(/ /g, '\xa0\xa0');
};
</script>
</body>
</html>
启动服务,验证结果:
网友评论