关键词:
以前面的博客为基础,最近一篇为Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存。本篇博客主要介绍了Spring Boot集成 Web Socket进行日志的推送,并实时显示在页面上。
1.导入jar包
第一个jar包是websocket的,第二个jar包是关于环形队列的jar包,本案例是通过本地队列存储日志。有条件的话,最好通过中间件存储(eg:redis,mq……)。通过本地队列存储日志会存在日志丢失的情况,且日志量太大,会把页面卡死。
1 <!--begin web socket--> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-websocket</artifactId> 5 </dependency> 6 <dependency> 7 <groupId>com.lmax</groupId> 8 <artifactId>disruptor</artifactId> 9 <version>3.4.2</version> 10 </dependency> 11 <!--end web socket-->
2.增加监听器
(1).在logback中增加监听器
并根据logback编写相应的监听器ProcessLogFilter
1 @Service 2 public class ProcessLogFilter extends Filter<ILoggingEvent> { 3 4 @Override 5 public FilterReply decide(ILoggingEvent event) { 6 LoggerMessage loggerMessage = new LoggerMessage( 7 event.getMessage() 8 , DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())), 9 event.getThreadName(), 10 event.getLoggerName(), 11 event.getLevel().levelStr 12 ); 13 LoggerDisruptorQueue.publishEvent(loggerMessage); 14 return FilterReply.ACCEPT; 15 } 16 }
该监听器将监听的日志消息推送到本地消息队列中,然后页面通过 Web Socket 去此队列获取日志信息,从而在页面显示
(2).编写日志处理器
1 //进程日志事件内容载体 2 @Data 3 @NoArgsConstructor 4 @AllArgsConstructor 5 public class LoggerEvent { 6 private LoggerMessage log; 7 }
1 /** 2 * Content :进程日志事件工厂类 3 */ 4 public class LoggerEventFactory implements EventFactory<LoggerEvent> { 5 @Override 6 public LoggerEvent newInstance() { 7 return new LoggerEvent(); 8 } 9 }
1 /** 2 * Content :进程日志事件处理器 3 */ 4 @Component 5 public class LoggerEventHandler implements EventHandler<LoggerEvent> { 6 7 @Autowired 8 private SimpMessagingTemplate messagingTemplate; 9 10 @Override 11 public void onEvent(LoggerEvent stringEvent, long l, boolean b) { 12 messagingTemplate.convertAndSend("/topic/pullLogger", stringEvent.getLog()); 13 } 14 }
日志事件处理器的作用是监听本地环形队列中的消息,如果有消息,就会将这些消息推送到 Socket 管道中
(3).编写页面
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <title>欢迎页</title> 7 <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> 8 <script src="plugins/jQuery/jquery-2.2.3.min.js"></script> 9 <script src="js/websocket/sockjs.min.js"></script> 10 <script src="js/websocket/stomp.min.js"></script> 11 </head> 12 <body> 13 <div class="panel panel-default"> 14 <h1>jvm进程内的日志</h1> 15 <button onclick="openSocket()">开启日志</button> 16 <button onclick="closeSocket()">关闭日志</button> 17 <div id="log-container" style="height: 600px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;"> 18 <div></div> 19 </div> 20 </div> 21 <script> 22 var stompClient = null; 23 $(document).ready(function () { 24 openSocket(); 25 }); 26 27 function openSocket() { 28 if (stompClient == null) { 29 var socket = new SockJS('http://localhost:8080/websocket?token=kl'); 30 stompClient = Stomp.over(socket); 31 stompClient.connect({token: "kl"}, function (frame) { 32 stompClient.subscribe('/topic/pullLogger', function (event) { 33 var content = JSON.parse(event.body); 34 $("#log-container div").append("<font color='red'>" + content.timestamp + "</font>|<font color='highlight'>" + content.level + "</font> |<font color='green'>" + content.threadName + "</font>| <font color='boldMagenta'>" + content.className + "</font>|<font color='cyan'>" + content.body + "</font>").append("<br/>"); 35 $("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height()); 36 }, { 37 token: "kltoen" 38 }); 39 }); 40 } 41 } 42 43 function closeSocket() { 44 if (stompClient != null) { 45 stompClient.disconnect(); 46 stompClient = null; 47 } 48 } 49 </script> 50 </body> 51 </html>
页面链接web Socket服务器,如果有消息,就能获取
(4).其他辅助类
环形本地队列类
1 package com.learn.hello.system.common.queue; 2 3 import com.learn.hello.modules.entity.LoggerMessage; 4 import com.learn.hello.system.common.event.LoggerEvent; 5 import com.learn.hello.system.common.event.LoggerEventFactory; 6 import com.learn.hello.system.common.event.LoggerEventHandler; 7 import com.lmax.disruptor.RingBuffer; 8 import com.lmax.disruptor.dsl.Disruptor; 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.stereotype.Component; 11 12 import java.util.concurrent.Executor; 13 import java.util.concurrent.Executors; 14 15 /** 16 * Content :Disruptor 环形队列 17 */ 18 @Component 19 public class LoggerDisruptorQueue { 20 21 private Executor executor = Executors.newCachedThreadPool(); 22 23 // The factory for the event 24 private LoggerEventFactory factory = new LoggerEventFactory(); 25 26 27 // Specify the size of the ring buffer, must be power of 2. 28 private int bufferSize = 2 * 1024; 29 30 // Construct the Disruptor 31 private Disruptor<LoggerEvent> disruptor = new Disruptor<>(factory, bufferSize, executor); 32 ; 33 34 35 private static RingBuffer<LoggerEvent> ringBuffer; 36 37 38 @Autowired 39 LoggerDisruptorQueue(LoggerEventHandler eventHandler) { 40 disruptor.handleEventsWith(eventHandler); 41 this.ringBuffer = disruptor.getRingBuffer(); 42 disruptor.start(); 43 } 44 45 public static void publishEvent(LoggerMessage log) { 46 long sequence = ringBuffer.next(); // Grab the next sequence 47 try { 48 LoggerEvent event = ringBuffer.get(sequence); // Get the entry in the Disruptor 49 // for the sequence 50 event.setLog(log); // Fill with data 51 } finally { 52 ringBuffer.publish(sequence); 53 } 54 } 55 56 }
消息实体类
1 package com.learn.hello.modules.entity; 2 3 import lombok.AllArgsConstructor; 4 import lombok.Data; 5 import lombok.NoArgsConstructor; 6 7 // 日志实体类 8 @Data 9 @AllArgsConstructor 10 @NoArgsConstructor 11 public class LoggerMessage { 12 private String body; 13 private String timestamp; 14 private String threadName; 15 private String className; 16 private String level; 17 }
3.效果
页面中的颜色可以自行设置
.
springboot入门二十,添加websocket支持
项目基本配置参考SpringBoot入门一,使用myEclipse新建一个SpringBoot项目,使用myEclipse新建一个SpringBoot项目即可。此示例springboot的版本已经升级到2.2.1.RELEASE,具体步骤如下:1.pom.xml添加以下配置信息<!--4.引入websocket支持--><depende... 查看详情
springboot集成websocket
websocket是全双工通信协议,目前html5支持,如果是app端的话可能不支持,建议app端实现通过tcp握手长连接实现通信,这里暂不研究。首先websocket是一个协议,需要了解一下 第一步先引入starter1<dependency>2<groupId>org.spring... 查看详情
将 Java WebSockets (JSR-356) 与 SpringBoot 集成
】将JavaWebSockets(JSR-356)与SpringBoot集成【英文标题】:IntegratingJavaWebSockets(JSR-356)withSpringBoot【发布时间】:2017-07-1618:33:00【问题描述】:在SpringBoot中部署websocket时遇到问题。我已经尝试了很多基于https://spring.io/blog/2013/05/23/spring-fra... 查看详情
项目总结48:springboot集成websocket案例(代码片段)
项目总结48:Springboot集成Websocket案例 Springboot集成Websocket的具体实现由很多方式,但原理是一样的;先放一个具体的案例 pom.xml jar依赖<!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId... 查看详情
springboot——springboot集成websocket实现简单的多人聊天室(代码片段)
文章目录:1.什么是WebSocket?2.Java中的WebSocketAPI2.1WebSocket开发中的相关注解及API方法2.2前端技术对WebSocket的支持3.多人聊天室的实现源码3.1pom文件中添加相关依赖2.2在核心配置文件中配置视图解析器2.3加入相关静态资源文... 查看详情
springboot入门到精通-springboot集成ssm开发项目(代码片段)
SpringBoot入门到精通系列SpringBoot入门到精通-Spring的注解编程(一)SpringBoot入门到精通-SpringBoot入门(二)SpringBoot入门到精通-Spring的基本使用(三)SpringBoot入门到精通-SpringBoot集成SSM(四)前言上一篇文章我们讲的是SpringBoot的基本用法,... 查看详情
springboot集成websocket,轻松实现信息推送!
在一次项目开发中,使用到了Netty网络应用框架,以及MQTT进行消息数据的收发,这其中需要后台来将获取到的消息主动推送给前端,于是就使用到了MQTT,特此记录一下。一、什么是websocket?WebSocket协议是基于TCP的一种新的网络... 查看详情
springboot入门:集成quartz定时任务
本片文章续《SpringBoot入门(八):集成RabbitMQ消息队列》,关于Quartz定时任务请参考《Quartz的基本使用之入门(2.3.0版本)》springboot实现定时任务,除了集成Quartz外,还可以直接使用scheduler注解。使用1个简单的注解就可以完成... 查看详情
springboot入门:集成rabbitmq消息队列
本片文章续《SpringBoot入门(七):集成swagger2》,关于RabbitMQ的介绍请参考《java基础(六):RabbitMQ入门》1.增加依赖1<!--rabbitMq-->2<dependency>3<groupId>org.springframework.boot</groupId>4<artifactId>spring 查看详情
001.camunda入门(springboot集成篇)
参考技术Acamunda框架与springboot的集成Camunda是基于Java语言,支持BPMN标准的工作流和流程自动化框架,并且还支持CMMN规范,DMN规范。具体组件如下图(引用官方图): 查看详情
springboot入门:集成swagger2
本片文章是基于前一篇写的,《SpringBoot入门(六):集成treetable和zTree实现树形图》,本篇主要介绍了springboot集成swagger2。关于swagger的介绍,自行谷歌。我这里有在网上购买的相关视频资料,有需要可以呼叫我。1.引入相关依赖... 查看详情
springboot+vue3集成使用websocket(代码片段)
...ocket</artifactId></dependency>增加配置类,声明该springboot项目使用websocket@ConfigurationpublicclassWebSocketConfig@BeanpublicServerEndpointExporterserverEndpointExporter()returnnewServerEndpointExporter();第三步,新建包增加业务代码:... 查看详情
springboot+vue3集成使用websocket(代码片段)
...ocket</artifactId></dependency>增加配置类,声明该springboot项目使用websocket@ConfigurationpublicclassWebSocketConfig@BeanpublicServerEndpointExporterserverEndpointExporter()returnnewServerEndpointExporter();第三步,新建包增加业务代码:... 查看详情
springboot入门:集成shiro实现登陆认证和权限管理
本文是接着上篇博客写的:Springboot入门(三):SpringBoot集成结合AdminLTE(Freemarker),利用generate自动生成代码,利用DataTable和PageHelper进行分页显示。按照前面的博客,已经可以搭建一个简单的SpringBoot系统,本篇博客继续对此系统... 查看详情
springboot集成websocket,实现后台向前端推送信息(代码片段)
前言在一次项目开发中,使用到了Netty网络应用框架,以及MQTT进行消息数据的收发,这其中需要后台来将获取到的消息主动推送给前端,于是就使用到了MQTT,特此记录一下。一、什么是websocket?WebSocket协... 查看详情
springboot集成websocket,实现后台向前端推送信息(代码片段)
前言在一次项目开发中,使用到了Netty网络应用框架,以及MQTT进行消息数据的收发,这其中需要后台来将获取到的消息主动推送给前端,于是就使用到了MQTT,特此记录一下。一、什么是websocket?WebSocket协... 查看详情
springboot入门:集成aop进行日志管理
本篇文章是接着Springboot入门(四):集成Shiro实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了Pagehelper+MyBatis分页查询,Generator代码自动生成器,Shiro登录及权限管理。本篇博客主要... 查看详情
springboot学习shiro快速入门及与springboot集成(代码片段)
...架构(外部)1.4、Shiro架构(内部)2、HelloWorld2.1、快速实践3、SpringBoot集成3.1、SpringBoot整合Shiro环境搭建3.2、Shiro实现登录拦截3.3、Shiro实现用户认证3.4、Shiro整合Mybatis3.5、Shiro实现用户授权 查看详情