Spring Boot webscoket 广播监控信息到页面

禅あ思 2020-12-25 13:21:02 ⋅ 742 阅读
一、maven 依赖
 
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
 
 
二、启用WebSocket
 
package com.itunion.example;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
 
/**
* @author qiao
* @version 2020-12-25
*/
@Configuration
public class WebSocketConfig {
    /**
     * ServerEndpointExporter 作用
     *
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
 
三、开放接口
package com.itunion.example.web;
 
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
import javax.annotation.PostConstruct;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
 
/**
* @author qiao
* @version 2020-12-25
*/
@Slf4j
@ServerEndpoint("/api/monitor/socket")
@Controller
@RequestMapping("/monitor")
public class Monitors {
 
    @GetMapping
    public String index(){
        return "monitor";
    }
 
    @PostConstruct
    public void init(){
        new Thread(() -> {
            // 模拟监控信息
            while (true) {
                try {
                    sendMessage("获取到的监控信息...");
                    Thread.sleep(new Random().nextInt(5000));
                } catch (InterruptedException e) {
                    break;
                }
            }
        }).start();
 
    }
 
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();
 
    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
 
    //异步广播内容
    public void sendMessage(Session session, String content) {
        session.getAsyncRemote().sendText(content);
    }
 
    //异步广播内容
    public void sendMessage(String content) {
        final Set<Map.Entry<String, Session>> entries = sessionPools.entrySet();
        for (Map.Entry<String, Session> entry : entries) {
            final Session session = entry.getValue();
            session.getAsyncRemote().sendText(content);
        }
    }
 
    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session) {
        sessionPools.put(session.getId(), session);
        addOnlineCount();
        sendMessage(session, "开始获取监控信息");
    }
 
    //关闭连接时调用
    @OnClose
    public void onClose(Session session) {
        sessionPools.remove(session.getId());
        subOnlineCount();
    }
 
    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        sessionPools.remove(session.getId());
        log.info("onError: {}", session.getId(), throwable);
    }
 
    private static void addOnlineCount() {
        final int val = onlineNum.incrementAndGet();
        log.info("当前人数为:{}", val);
    }
 
    private static void subOnlineCount() {
        final int val = onlineNum.decrementAndGet();
        log.info("当前人数为:{}", val);
    }
 
}

四、前端连接
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监控页面</title>
</head>
<body>
 
<textarea id="content" rows="10" style="width: 100%" readonly></textarea>
 
<script>
    function openSocket() {
        if(typeof(WebSocket) == "undefined") {
            alert("您的浏览器不支持WebSocket");
        }else{
            console.log("connect...");
            //实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接
            var socketUrl="ws://localhost:8080/api/monitor/socket";
 
            var socket = new WebSocket(socketUrl);
            //打开事件
            socket.onopen = function() {
                console.log("websocket已打开");
            };
            //获得消息事件
            socket.onmessage = function(event) {
                console.log(event);
                log(event.data);
            };
            //关闭事件
            socket.onclose = function() {
                log("close");
            };
            //发生了错误事件
            socket.onerror = function () {
                log("error");
            };
            return socket;
        }
    }
   
    function log(msg) {
        var ele = document.getElementById("content");
        ele.innerHTML += msg + "\n";
        ele.scrollTop = ele.scrollHeight;
    }
 
    openSocket();
</script>
</body>
</html>
 
五、启动服务访问页面
 


全部评论: 0

    我有话说:

    使用Spring Boot Actuator监控应用

    Actuator是Spring Boot提供的对应用系统的自省和监控的集成功能,可以对应用系统进行配置查看

    Spring Boot 开发利器

    工欲善其事,必先利其器每次创建新项目都要找各种依赖的包是不是很烦?今天给大家介绍下 Spring 官方提供的 Online 项目脚手架

    Spring Boot 2.4.0-RC1, 2.1.18, 2.2.11 和 2.3.5 发布

    Spring Boot 多个分支发布了新版本,分别是 2.4.0-RC1, 2.1.18, 2.2.11 和 2.3.5。 Spring Boot 2.4.0-RC1 此版本是 

    架构实战篇(十七):Spring Boot Assembly 整合 thymeleaf

    如何让服务器上的 sprig boot 项目升级变的方便快捷

    码云推荐:一个优秀的分布式spring boot/Spring Cloud API限流框架,特别适合微服务架构

    一个优秀的分布式spring boot/Spring Cloud API限流框架,特别适合微服务架构.

    微服务架构学习笔记:gRPC Spring Boot Starter 2.2.0 发布,及使用步骤

    gRPC Spring Boot Starter 项目是一个 gRPC 的 Spring Boot 模块。内嵌一个 gRPC Server 对外提供服务,并支持 Spring Cloud 的服务发现

    Spring Boot 2.1.0新特性 ,准备好了吗?!

    Spring Boot官方在10月30号正式发布了v2.1.0.RELEASE版本,由于本人最近比较忙,直到今天才着重抽空学习和了解这次升级一共带来了9大新特性,根据官方描述,正在逐渐支持 java

    架构实战篇(十三):Spring Boot Logback 邮件通知

    日志对于应用程序来说是非常重要的,当你的程序报错了,而你又不知道是多么可怕的一件事情,本文使用logback把程序报错信息邮件开发者

    微服务架构实战篇(六):Spring boot2.x 集成阿里大鱼短信接口详解与Demo

    Spring boot2.x 集成阿里大鱼短信接口,发送短信验证码及短信接口详解。

    架构实战篇(三)-Spring Boot架构搭建RESTful API案例

    之前分享了Spring Boot 整合Swagger 让API可视化和前后端分离架构 受到了大家一致好评 ,本节就接着上节的代码做了详细的查询代码的补充和完善并搭建RESTful API架构案例。

    架构实战篇(七):Spring Boot Data JPA 快速入门

    Spring Data JPA 是Spring Data 的一个子项目,它通过提供基于JPA的Repository极大了减少了操作JPA的代码。

    架构实战篇(六):Spring Boot RestTemplate的使用

    RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

    架构实战篇(十五):Spring Boot 解耦之事件驱动

    通过使用spring 事件来解决业务代码的耦合

    架构实战篇(八):Spring Boot 集成 Druid 数据源监控

    Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。

    架构实战篇(一)-Spring Boot+MyBatis基础架构搭建

    Spring的追求一定是简单点简单点,让java的开发变得更加简单、容易。瞧瞧的告诉你们直接copy就能用哦~~~

    运维监控软件 wgcloud 更新,v3.2.7 重构告警模块

    WGCLOUD,server端基于springboot开发,agent端使用go编写。支持高并发高性能,核心模块包括:服务器集群监控,ES集群状态监控,CPU监控,内存监控,数据监控,docker

    Spring Boot 快速配置拦截器

    作者:边鹏_尛爺鑫原文链接:https://my.oschina.net/bianxin/blog/2876

    Spring Boot Admin 2.3.1 发布,轻量的图形化监控工具

    Spring Boot Admin 2.3.1 发布,这是一个错误修正版本。现在可以从 maven 仓库 下载,支持 2.3.0 平滑升级 <dependency>