美文网首页程序员
基于 WebSocket 实时推送服务日志

基于 WebSocket 实时推送服务日志

作者: 叫我宫城大人 | 来源:发表于2019-05-06 17:43 被阅读0次

    背景

    服务发生异常时,每次都登录服务器查看日志有些费时费力。

    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>
    

    启动服务,验证结果:

    参考文章

    相关文章

      网友评论

        本文标题:基于 WebSocket 实时推送服务日志

        本文链接:https://www.haomeiwen.com/subject/lqxdoqtx.html