Bootstrap

WebSocket定时推送数据随记

引入驱动

		<!-- websocket-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
			<version>2.7.1</version>
		</dependency>

添加socket配置类

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
@ServerEndpoint("/webSocket/{addressId}")
@Component
@Slf4j
public class WebSocketServer {
    //静态变量,用来记录当前在线连接数。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, List<Session>> sessionPools = new ConcurrentHashMap<>();

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                System.out.println("发送数据:" + message);
                session.getBasicRemote().sendText(message);
                System.out.println("消息发送完毕");
            }
        }
    }

    //给指定用户发送信息
    public void sendInfo(String addressId, String message) {
        List<Session> sessionList = sessionPools.get(addressId);
        try {
            if (!CollectionUtils.isEmpty(sessionList)) {
                for (Session session : sessionList) {
                    sendMessage(session, message);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 群发消息
    public void broadcast(String message) {
        for (ConcurrentHashMap.Entry<String, List<Session>> entry : sessionPools.entrySet()) {
            List<Session> sessionList = entry.getValue();
            sendMesInfo(sessionList, message);
        }
    }

    public void sendMesInfo(List<Session> sessionList, String message) {
        for (Session session : sessionList) {
            try {
                sendMessage(session, message);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "addressId") String addressId) {
        List<Session> sessionList = new ArrayList<>();
        if (sessionPools.containsKey(addressId)) {
            sessionList = sessionPools.get(addressId);
        } else {
            addOnlineCount();
        }
        sessionList.add(session);
        sessionPools.put(addressId, sessionList);
        System.out.println(addressId + "加入webSocket!当前人数为" + onlineNum);
        // 广播上线消息 TODO
        MsgCountDTO dto = new MsgCountDTO();
        dto.setNoticeNum(1);
        dto.setWarnNum(123);
        broadcast(JSON.toJSONString(dto, true));
    }

    //关闭连接时调用
    @OnClose
    public void onClose(Session session, @PathParam(value = "addressId") String addressId) {
        System.out.println("退出");
        List<Session> sessionList = sessionPools.get(addressId);
        boolean flag = true;
        if (!CollectionUtils.isEmpty(sessionList)) {
            if (1 == sessionList.size() && sessionList.contains(session)) {
                sessionPools.remove(addressId);
                subOnlineCount();
            } else if (1 != sessionList.size()) {
                sessionList.remove(session);
                sessionPools.put(addressId, sessionList);
            }
        }

        System.out.println(addressId + "断开webSocket连接!当前人数为" + onlineNum);
        // 广播下线消息
//        MsgCountDTO dto = new MsgCountDTO();
//        dto.setNoticeNum(1);
//        dto.setWarnNum(123);
//        broadcast(JSON.toJSONString(dto, true));
    }

    //收到客户端信息后,addressId
    // to=-1群发消息
    @OnMessage
    public void onMessage(String message) {
        System.out.println("server get" + message);
        //TODO
        MsgCountDTO dto = new MsgCountDTO();
        dto.setNoticeNum(1);
        dto.setWarnNum(123);
        broadcast(JSON.toJSONString(dto, true));
        //实际的所需数据  也可根据传入的信息进行接收者的指定
//        SocketMessageResponseDTO msg = JSON.parseObject(message, SocketMessageResponseDTO.class);
//        msg.setDate(Java8DateUtil.dateTimeFormat(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
//        if (msg.getTo().equals("-1")) {
//            broadcast(JSON.toJSONString(msg, true));
//        } else {
//            sendInfo(msg.getTo(), JSON.toJSONString(msg, true));
//        }
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

    public static AtomicInteger getOnlineNumber() {
        return onlineNum;
    }

    public static ConcurrentHashMap<String, List<Session>> getSessionPools() {
        return sessionPools;
    }
}

启动服务

访问:http://www.jsons.cn/websocket/
在地址栏中录入socket访问地址测试连接
在这里插入图片描述
服务端可以根据传递的参数进行不同数据的返回。

模拟后端定时触发进行数据推送

可以是满足某个条件后进行数据推送也可以是定时进行数据推送。此处举例为定时推送数据:
添加一个调度任务

@Component
@Slf4j
public class LargeScreenJob {

    @Resource
    private WebSocketServer socketServer;

    @Scheduled(cron = "0/5 * * * * ?")
    public void LargeScreenHandler() {
        log.info("报警数提醒job开始执行........");
        //TODO  业务数据

        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("msg", "发送消息 使其广播");
        socketServer.onMessage(JSON.toJSONString(paramMap));
        log.info("报警数提醒job执行结束........");
    }

}

启动服务:
服务端如图:
在这里插入图片描述
前端如图:
在这里插入图片描述

;