本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~

Github地址:https://github.com/Tyson0314/Java-learning


写在前面

此异常非彼异常,标题所说的异常是业务上的异常。

最近做了一个需求,消防的设备巡检,如果巡检发现异常,通过手机端提交,后台的实时监控页面实时获取到该设备的信息及位置,然后安排员工去处理。

因为需要服务端主动向客户端发送消息,所以很容易的就想到了用WebSocket来实现这一功能。

前端略微复杂,需要在一张位置分布图上进行鼠标描点定位各个设备和根据不同屏幕大小渲染,本文不做介绍,只是简单地用页面样式进行效果呈现。

绿色代表正常,红色代表异常

预期效果,未接收到请求前----->id为3的提交了异常,id为3的王五变成了红色

实现

前端:

直接贴代码

  1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8" />
5 <title>实时监控</title>
6 </head>
7 <style>
8 .item {
9 display: flex;
10 border-bottom: 1px solid #000000;
11 justify-content: space-between;
12 width: 30%;
13 line-height: 50px;
14 height: 50px;
15 }
16
17 .item span:nth-child(2){
18 margin-right: 10px;
19 margin-top: 15px;
20 width: 20px;
21 height: 20px;
22 border-radius: 50%;
23 background: #55ff00;
24 }
25 .nowI{
26 background: #ff0000 !important;
27 }
28 </style>
29 <body>
30 <div id="app">
31 <div v-for="item in list" class="item">
32 <span>{{item.id}}.{{item.name}}</span>
33 <span :class='item.state==-1?"nowI":""'></span>
34 </div>
35 </div>
36 </body>
37 <script src="./js/vue.min.js"></script>
38 <script type="text/javascript">
39 var vm = new Vue({
40 el: "#app",
41 data: {
42 list: [{
43 id: 1,
44 name: '张三',
45 state: 1
46 },
47 {
48 id: 2,
49 name: '李四',
50 state: 1
51 },
52 {
53 id: 3,
54 name: '王五',
55 state: 1
56 },
57 {
58 id: 4,
59 name: '韩梅梅',
60 state: 1
61 },
62 {
63 id: 5,
64 name: '李磊',
65 state: 1
66 },
67 ]
68 }
69 })
70
71 var webSocket = null;
72 if ('WebSocket' in window) {
73 //创建WebSocket对象
74 webSocket = new WebSocket("ws://localhost:18801/webSocket/" + getUUID());
75
76 //连接成功
77 webSocket.onopen = function() {
78 console.log("已连接");
79 webSocket.send("消息发送测试")
80 }
81 //接收到消息
82 webSocket.onmessage = function(msg) {
83 //处理消息
84 var serverMsg = msg.data;
85 var t_id = parseInt(serverMsg) //服务端发过来的消息,ID,string需转化为int类型才能比较
86 for (var i = 0; i < vm.list.length; i++) {
87 var item = vm.list[i];
88 if(item.id == t_id){
89 item.state = -1;
90 vm.list.splice(i,1,item)
91 break;
92 }
93 }
94 };
95
96 //关闭事件
97 webSocket.onclose = function() {
98 console.log("websocket已关闭");
99 };
100 //发生了错误事件
101 webSocket.onerror = function() {
102 console.log("websocket发生了错误");
103 }
104 } else {
105 alert("很遗憾,您的浏览器不支持WebSocket!")
106 }
107
108 function getUUID() { //获取唯一的UUID
109 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
110
111 var r = Math.random() * 16 | 0,
112 v = c == 'x' ? r : (r & 0x3 | 0x8);
113 return v.toString(16);
114 });
115 }
116 </script>
117 </html>
复制代码

后端:

项目结构是这样子的,后面的代码关键注释都有,就不重复描述了

1、新建SpringBoot工程,选择web和WebSocket依赖

2、配置application.yml

#端口
server:
port: 18801 #密码,因为接口不需要权限,所以加了个密码做校验
mySocket:
myPwd: jae_123
复制代码

3、WebSocketConfig配置类

 1 @Configuration
2 public class WebSocketConfig {
3
4 /**
5 * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
6 */
7 @Bean
8 public ServerEndpointExporter serverEndpointExporter(){
9 return new ServerEndpointExporter();
10 }
11 }
复制代码

4、WebSocketServer类,用来进行服务端和客户端之间的交互

 1 /**
2 * @author jae
3 * @ServerEndpoint("/webSocket/{uid}") 前端通过此URI与后端建立链接
4 */
5
6 @ServerEndpoint("/webSocket/{uid}")
7 @Component
8 public class WebSocketServer {
9
10 private static Logger log = LoggerFactory.getLogger(WebSocketServer.class);
11
12 //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
13 private static final AtomicInteger onlineNum = new AtomicInteger(0);
14
15 //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
16 private static CopyOnWriteArraySet<Session> sessionPools = new CopyOnWriteArraySet<Session>();
17
18 /**
19 * 有客户端连接成功
20 */
21 @OnOpen
22 public void onOpen(Session session, @PathParam(value = "uid") String uid){
23 sessionPools.add(session);
24 onlineNum.incrementAndGet();
25 log.info(uid + "加入webSocket!当前人数为" + onlineNum);
26 }
27
28 /**
29 * 连接关闭调用的方法
30 */
31 @OnClose
32 public void onClose(Session session) {
33 sessionPools.remove(session);
34 int cnt = onlineNum.decrementAndGet();
35 log.info("有连接关闭,当前连接数为:{}", cnt);
36 }
37
38 /**
39 * 发送消息
40 */
41 public void sendMessage(Session session, String message) throws IOException {
42 if(session != null){
43 synchronized (session) {
44 session.getBasicRemote().sendText(message);
45 }
46 }
47 }
48
49 /**
50 * 群发消息
51 */
52 public void broadCastInfo(String message) throws IOException {
53 for (Session session : sessionPools) {
54 if(session.isOpen()){
55 sendMessage(session, message);
56 }
57 }
58 }
59
60 /**
61 * 发生错误
62 */
63 @OnError
64 public void onError(Session session, Throwable throwable){
65 log.error("发生错误");
66 throwable.printStackTrace();
67 }
68
69 }
复制代码

5、WebSocketController类,用于进行接口测试

 1 @RestController
2 @RequestMapping("/open/socket")
3 public class WebSocketController {
4
5 @Value("${mySocket.myPwd}")
6 public String myPwd;
7
8 @Autowired
9 private WebSocketServer webSocketServer;
10
11 /**
12 * 手机客户端请求接口
13 * @param id 发生异常的设备ID
14 * @param pwd 密码(实际开发记得加密)
15 * @throws IOException
16 */
17 @PostMapping(value = "/onReceive")
18 public void onReceive(String id,String pwd) throws IOException {
19 if(pwd.equals(myPwd)){ //密码校验一致(这里举例,实际开发还要有个密码加密的校验的),则进行群发
20 webSocketServer.broadCastInfo(id);
21 }
22 }
23
24 }
复制代码

测试

1、打开前端页面,进行WebSocket连接

控制台输出,连接成功

2、因为是模拟数据,所以全部显示正常,没有异常提交时的页面呈现

3、接下来,我们用接口测试工具Postman提交一个异常

注意id为3的这个数据的状态变化

我们可以看到,id为3的王五状态已经变成异常的了,实时通讯成功。

最后

工作中有这方面关于实时监控的需求,可以参考一下哦。

原文:cnblogs.com/jae-tech/p/15409340.html


最后给大家分享一个Github仓库,上面有大彬整理的300多本经典的计算机书籍PDF,包括C语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,可以star一下,下次找书直接在上面搜索,仓库持续更新中~

Github地址https://github.com/Tyson0314/java-books

Spring Boot + WebSocket 实时监控异常的更多相关文章

  1. SpringBoot+WebSocket实时监控异常

    写在前面 此异常非彼异常,标题所说的异常是业务上的异常. 最近做了一个需求,消防的设备巡检,如果巡检发现异常,通过手机端提交,后台的实时监控页面实时获取到该设备的信息及位置,然后安排员工去处理. 因为 ...

  2. Spring Boot Admin2.X监控的服务context-path问题

    在使用Spring Boot Admin进行监控时,如果被监控的服务没有加context-path的话是不会有任何问题的,一旦服务加了context-path的配置,监控就会失败. 下图是正常情况的显 ...

  3. 玩转spring boot——websocket

    前言 QQ这类即时通讯工具多数是以桌面应用的方式存在.在没有websocket出现之前,如果开发一个网页版的即时通讯应用,则需要定时刷新页面或定时调用ajax请求,这无疑会加大服务器的负载和增加了客户 ...

  4. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  5. spring boot websocket stomp 实现广播通信和一对一通信聊天

    一.前言 玩.net的时候,在asp.net下有一个叫 SignalR 的框架,可以在ASP .NET的Web项目中实现实时通信.刚接触java寻找相关替代品,发现 java 体系中有一套基于stom ...

  6. (转)Spring Boot(二十):使用 spring-boot-admin 对 Spring Boot 服务进行监控

    http://www.ityouknow.com/springboot/2018/02/11/spring-boot-admin.html 上一篇文章<Spring Boot(十九):使用 Sp ...

  7. Spring Boot WebSocket从入门到放弃

    在构建Spring boot项目时已经提供webSocket依赖的勾选.webSocket是TCP之上的一个非常薄的轻量级层 ,webSocket主要的应用场景离不开即时通讯与消息推送,但只要应用程序 ...

  8. 微服务监控之三:Prometheus + Grafana Spring Boot 应用可视化监控

    一.Springboot增加Prometheus 1.Spring Boot 应用暴露监控指标,添加如下依赖 <dependency> <groupId>org.springf ...

  9. 拒绝黑盒应用-Spring Boot 应用可视化监控

    图文简介 逻辑关系 效果演示 快速开始 1.Spring Boot 应用暴露监控指标[版本 1.5.7.RELEASE] 首先,添加依赖如下依赖: <dependency> <gro ...

  10. Springboot 系列(十七)迅速使用 Spring Boot Admin 监控你的 Spring Boot 程序,支持异常邮件通知

    1. Spring Boot Admin 是什么 Spring Boot Admin 是由 codecentric 组织开发的开源项目,使用 Spring Boot Admin 可以管理和监控你的 S ...

随机推荐

  1. MybatisPlus Lambda表达式 聚合查询 分组查询 COUNT SUM AVG MIN MAX GroupBy

    一.序言 众所周知,MybatisPlus在处理单表DAO操作时非常的方便.在处理多表连接连接查询也有优雅的解决方案.今天分享MybatisPlus基于Lambda表达式优雅实现聚合分组查询. 由于视 ...

  2. 2022春每日一题:Day 38

    题目[USACO17JAN]Promotion Counting P 从根节点dfs一遍,树状数组维护进入和出去时这个节点的贡献,一减就是答案 代码: #include <cstdio> ...

  3. 面试官不按套路,竟然问我Java线程池是怎么统计线程空闲时间?

    背景介绍: 你刚从学校毕业后,到新公司实习,试用期又被毕业,然后你又不得不出来面试,好在面试的时候碰到个美女面试官! 面试官: 小伙子,我看你简历上写的项目中用到了线程池,你知道线程池是怎样实现复用线 ...

  4. 基于python的数学建模---pulp库

    instance 代码: import pulp z = [2, 3, 1] a = [[1, 4, 2], [3, 2, 0]] b = [8, 6] aeq = [[1,2,4]] beq = [ ...

  5. Project facet Java version 13 is not supported.

    问题 导入的文件运行时出现报错:Project facet Java version 13 is not supported. 大概就是版本不支持,看了下自己的Java版本是1.8的,修改下版本即可运 ...

  6. python选课系统项目详解

    选课系统项目详解 选课系统简介及分析 选课系统架构设计分析 选课系统目录设计 管理员视图 注册 登录 创建学校 创建课程 创建讲师 学生视图 注册 登录 选择学校 选择课程 查看分数 教师视图 登录 ...

  7. java:绘制图形

    java绘图类:Graphics类 绘图是高级程序中必备的技术,在很多方面都能用到,如:绘制闪屏图片,背景图片和组件外观等. 1.Graphics类 Graphics类是所有图形上下文的抽象基类,Gr ...

  8. 使用repo上传代码

    前言~ repo是一款安卓用于管理源码的工具,由python实现,基于git工具 本文介绍了repo的常用使用方式. 一,下载代码 1. repo init 初始化命令 此命令常用选项就那几个,此处取 ...

  9. kettel

    下载教程:(目前最高版本7.1) 1.网址:https://community.hitachivantara.com/docs/DOC-1009855 2.

  10. JavaScript入门⑦-DOM操作大全

    JavaScript入门系列目录 JavaScript入门①-基础知识筑基 JavaScript入门②-函数(1)基础{浅出} JavaScript入门③-函数(2)原理{深入}执行上下文 JavaS ...