<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
今天來做個有趣的東西,就是實時將系統紀錄檔輸出的前端web頁面,因為是實時輸出,所有第一時間就想到了使用webSocket,而且在spring boot中,使用websocket超級方便,閱讀本文,你會接觸到以下關鍵詞相關技術,WebSocket(stopmp伺服器端),stomp協定,sockjs.min.js,stomp.min.js(stomp使用者端),本文使用到的其實就是使用spring boot自帶的webSocket模組提供stomp的伺服器端,前端使用stomp.min.js做stomp的使用者端,使用sockjs來連結,前端訂閱後端紀錄檔端點的訊息,後端實時推播,達到紀錄檔實時輸出到web頁面的目的,效果如下圖
STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,簡單(流)文字定向訊息協定,它提供了一個可互操作的連線格式,允許STOMP使用者端與任意STOMP訊息代理(Broker)進行互動。STOMP協定由於設計簡單,易於開發使用者端,因此在多種語言和多種平臺上得到廣泛地應用。
STOMP協定的前身是TTMP協定(一個簡單的基於文字的協定),專為訊息中介軟體設計。
STOMP是一個非常簡單和容易實現的協定,其設計靈感源自於HTTP的簡單性。儘管STOMP協定在伺服器端的實現可能有一定的難度,但使用者端的實現卻很容易。例如,可以使用Telnet登入到任何的STOMP代理,並與STOMP代理進行互動。
下面是具體的步驟,主要是紀錄檔資訊的獲取和紀錄檔資訊的推播,不多說,上程式碼
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
/** * Created by kl on 2017/10/9. * Content :紀錄檔訊息實體,注意,這裡為了減少篇幅,省略了get,set程式碼 */ public class LoggerMessage{ private String body; private String timestamp; private String threadName; private String className; private String level; public LoggerMessage(String body, String timestamp, String threadName, String className, String level) { this.body = body; this.timestamp = timestamp; this.threadName = threadName; this.className = className; this.level = level; } public LoggerMessage() { } }
作為紀錄檔系統輸出的紀錄檔的一個臨時載體
public class LoggerQueue { //佇列大小 public static final int QUEUE_MAX_SIZE = 10000; private static LoggerQueue alarmMessageQueue = new LoggerQueue(); //阻塞佇列 private BlockingQueueblockingQueue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE); private LoggerQueue() { } public static LoggerQueue getInstance() { return alarmMessageQueue; } /** * 訊息入隊 * @param log * @return */ public boolean push(LoggerMessage log) { return this.blockingQueue.add(log);//佇列滿了就丟擲異常,不阻塞 } /** * 訊息出隊 * @return */ public LoggerMessage poll() { LoggerMessage result = null; try { result = this.blockingQueue.take(); } catch (InterruptedException e) { e.printStackTrace(); } return result; } }
1.定義Logfilter攔截輸出紀錄檔
public class LogFilter extends Filter{ @Override public FilterReply decide(ILoggingEvent event) { LoggerMessage loggerMessage = new LoggerMessage( event.getMessage() , DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())), event.getThreadName(), event.getLoggerName(), event.getLevel().levelStr ); LoggerQueue.getInstance().push(loggerMessage); return FilterReply.ACCEPT; } }
2.設定logback.xml,新增我們自定義的filter
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true"> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}" /> <include resource="org/springframework/boot/logging/logback/file-appender.xml" /> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>utf8</charset> </encoder> <filter class="com.example.websocket.LogFilter"></filter> </appender> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="CONSOLE" /> </root> </configuration>
@Configuration public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/websocket") .setAllowedOrigins("http://localhost:8976") .withSockJS(); } }
注意:為了連線安全,setAllowedOrigins設定的允許連線的源地址,如果在非這個設定的地址下發起連線會報403,進一步還可以使用addInterceptors設定攔截器,來做相關的鑑權操作
@SpringBootApplication @EnableScheduling @EnableWebSocketMessageBroker public class WebsocketApplication { private Logger logger = LoggerFactory.getLogger(WebsocketApplication.class); public static void main(String[] args) { SpringApplication.run(WebsocketApplication.class, args); } @Autowired private SimpMessagingTemplate messagingTemplate; int info=1; @Scheduled(fixedRate = 1000) public void outputLogger(){ logger.info("測試紀錄檔輸出"+info++); } /** * 推播紀錄檔到/topic/pullLogger */ @PostConstruct public void pushLogger(){ ExecutorService executorService=Executors.newFixedThreadPool(2); Runnable runnable=new Runnable() { @Override public void run() { while (true) { try { LoggerMessage log = LoggerQueue.getInstance().poll(); if(log!=null){ if(messagingTemplate!=null) messagingTemplate.convertAndSend("/topic/pullLogger",log); } } catch (Exception e) { e.printStackTrace(); } } } }; executorService.submit(runnable); executorService.submit(runnable); } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>WebSocket Logger</title> <script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.js"></script> <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script> <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script> </head> <body> <button onclick="openSocket()">開啟紀錄檔</button><button onclick="closeSocket()">關閉紀錄檔</button> <div id="log-container" style="height: 450px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;"> <div></div> </div> </body> <script> var stompClient = null; $(document).ready(function() {openSocket();}); function openSocket() { if(stompClient==null){ var socket = new SockJS('http://localhost:8084/websocket?token=kl'); stompClient = Stomp.over(socket); stompClient.connect({token:"kl"}, function(frame) { stompClient.subscribe('/topic/pullLogger', function(event) { var content=JSON.parse(event.body); $("#log-container div").append(content.timestamp +" "+ content.level+" --- ["+ content.threadName+"] "+ content.className+" :"+content.body).append("<br/>"); $("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height()); },{ token:"kltoen" }); }); } } function closeSocket() { if (stompClient != null) { stompClient.disconnect(); stompClient=null; } } </script> </body> </html>
參考地址:
stomp.js使用者端:http://jmesnil.net/stomp-websocket/doc/
scok.js使用者端:https://github.com/sockjs/sockjs-client
spring webSocket:https://docs.spring.io/spring/docs/
以上就是spring boot整合WebSocket到web頁面實時輸出的詳細內容,更多關於spring boot整合WebSocket實時輸出到web的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45