使用WebSocket实现从后端向前端推送信息
triumph qy 2024-07-09 17:03:02 阅读 94
本文做一个简单的应用,使用单例模式+WebSocket向前端提示需要处理的消息数量。
“+”和“-”表示用户端做的操作;“查看消息[8]”表示管理端需要处理的消息。
引入依赖
<code> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependencies>
注入ServerEndpointExporter,这个Bean会自动注册使用了@ServerPoint注解声明的类。
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
创建数量单例,这里的单例是本文主要向前端推送的内容。
由于此单例需要频繁使用,所以创建为饿汉式单例。
public class CountSingle {
private Integer count = 10;
private final static CountSingle countSingle = new CountSingle();
public static Integer getCount() {
return getInstance().count;
}
public static synchronized void setCount(OperEnum operEnum) {
if (operEnum == OperEnum.ADD) {
getInstance().count++;
}
if (operEnum == OperEnum.SUB) {
getInstance().count--;
}
}
public static CountSingle getInstance() {
return countSingle;
}
}
创建操作枚举,规范代码。
public enum OperEnum {
ADD(1), SUB(2);
private final Integer code;
OperEnum(int code) {
this.code = code;
}
public Integer getCode() {
return code;
}
}
WebSocket服务类创建。
@Component
@ServerEndpoint("/websocket")
public class WebSocketServer {
private static final CopyOnWriteArraySet<WebSocketServer> connections = new CopyOnWriteArraySet<>();
private Session session;
@OnOpen
public void onOpen(Session session) {
this.session = session;
connections.add(this);
this.sendMessage(String.valueOf(CountSingle.getCount()));
System.out.println("新建连接: " + session.getId());
}
@OnClose
public void onClose() {
connections.remove(this);
System.out.println("连接关闭: " + session.getId());
}
@OnError
public void onError(Throwable error) {
error.printStackTrace();
}
private void sendMessage(String message) {
try {
this.session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void broadcast(String message) {
for (WebSocketServer client : connections) {
client.sendMessage(message);
}
}
}
创建控制器,对于CountSingle的count数量加减的操作。
@RestController
public class CountController {
@GetMapping("add")
public void add() {
CountSingle.setCount(OperEnum.ADD);
WebSocketServer.broadcast(String.valueOf(CountSingle.getCount()));
}
@GetMapping("sub")
public void sub() {
CountSingle.setCount(OperEnum.SUB);
WebSocketServer.broadcast(String.valueOf(CountSingle.getCount()));
}
}
前端功能编写。使用jQuery的Ajax发送请求(或给查看信息后面的徽章赋值)、Layui的徽章组件编写主要样式。
<!DOCTYPE html>
<html lang="en">code>
<head>
<meta charset="UTF-8">code>
<meta name="viewport" content="width=device-width, initial-scale=1.0">code>
<title>Document</title>
<script src="/lib/jquery-3.4.1.min.js"></script>code>
<script src="/lib/layui-v2.5.5/layui.js"></script>code>
<link rel="stylesheet" href="/lib/layui-v2.5.5/css/layui.css">code>
<style>
div {
text-align: center;
}
</style>
</head>
<body>
<div>
<button class="layui-btn layui-btn-sm layui-btn-normal" onclick="add()">+</button>code>
<button class="layui-btn layui-btn-sm layui-btn-warm" onclick="sub()">-</button>code>
<button class="layui-btn">查看消息<span class="layui-badge layui-bg-gray" id="count"></span></button>code>
</div>
let socket = new WebSocket("ws://localhost:8080/websocket");
socket.onmessage = function (event) {
$("#count").text(event.data);
};
function add() {
$.ajax({
url: '/add', // 请求的 URL
type: 'GET', // 请求方法:GET、POST 等
dataType: 'json', // 预期服务器返回的数据类型
});
}
function sub() {
$.ajax({
url: '/sub', // 请求的 URL
type: 'GET', // 请求方法:GET、POST 等
dataType: 'json', // 预期服务器返回的数据类型
});
}
最后实现的效果。这里需要使用两个浏览器才能看到效果。
首先打开Edge浏览器(初始)。这里为了更好的看到效果,加上了一个显示时间的组件。
点击加号按钮。
打开Chrome浏览器查看到消息成功推送。
最后附上gitee地址:WebsocketTest: 本系统做一个简单的应用,使用单例模式+WebSocket向前端提示需要处理的消息数量。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。