程序git:https://gitee.com/juncaoit/websocketpro
1.引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.@ServerEndpoint
@ServerEndpoint注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
/** * 会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint * 要注意,如果使用独立的servlet容器, * 而不是直接使用springboot的内置容器, * 就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。 */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }
3.服务器方法
package com.jun.send.websocket; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @Component @Slf4j @ServerEndpoint("/webSocket/{category}") public class WebSocketServer { /** * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 */ private static int onlineCount = 0; /** * concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。 */ public static ConcurrentHashMap<WebSocketServer, String> webSocketMap = new ConcurrentHashMap<>(); /** * 与某个客户端的连接会话,需要通过它来给客户端发送数据 */ private Session session; /** * 连接建立成 * 功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam("category") String category) { this.session = session; webSocketMap.put(this, category); log.info("【websocket消息】有新的连接,总数:{}", webSocketMap.size()); sendInfo("连接成功"); } /** * 连接关闭 * 调用的方法 */ @OnClose public void onClose() { webSocketMap.remove(this); log.info("【websocket消息】连接断开,总数:{}", webSocketMap.size()); } /** * 收到客户端消 * 息后调用的方法 * * @param message 客户端发送过来的消息 **/ @OnMessage public void onMessage(String message) { log.info("【websocket消息】收到客户端发来的消息:{}", message); } /** * @param error */ @OnError public void onError(Throwable error) { log.error("发和错误,原因:" + error.getMessage()); error.printStackTrace(); } /** * 实现服务 * 器主动推送 */ public void sendMessage(String message, String category) { for (Map.Entry<WebSocketServer, String> entry : webSocketMap.entrySet()) { WebSocketServer webSocketServer = entry.getKey(); log.info("【websocket消息】广播消息,category={}, message={}", category, message); try { webSocketServer.session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } } /** * 发送自定 * 义消息 **/ public void sendInfo(String message) { try { this.session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } }
4.job定时推送给前端数据
package com.jun.send.job; import com.alibaba.fastjson.JSON; import com.jun.send.model.WpDataInfo; import com.jun.send.websocket.WebSocketServer; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Date; import java.util.concurrent.ConcurrentHashMap; @Slf4j @Service public class SendMessageJob { @Resource private WebSocketServer webSocketServer; @Scheduled(cron = "0 */2 * * * ?") public void sendMessage() { ConcurrentHashMap<WebSocketServer, String> webSocketMap = WebSocketServer.webSocketMap; if (webSocketMap.size() <= 0) { log.info("没有session,不进行处理,不进行推送数据"); return; } WpDataInfo wpDataInfo = new WpDataInfo(); wpDataInfo.setDeviceNo("34-ME-01"); wpDataInfo.setCreateTime("2022-08-17 00:00:00"); webSocketServer.sendMessage(JSON.toJSONString(wpDataInfo), "wp"); log.info("发送的数据成功"); } }
5.前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket client</title>
<script type="text/javascript">
var socket;
if (typeof (WebSocket) == "undefined"){
alert("This explorer don't support WebSocket")
}
function connect() {
//Connect WebSocket server
socket =new WebSocket("ws://127.0.0.1:8099/webSocket/wp");
//open
socket.onopen = function () {
alert("WebSocket is open");
}
//Get message
socket.onmessage = function (msg) {
alert("Message is " + msg);
}
//close
socket.onclose = function () {
alert("WebSocket is closed");
}
//error
socket.onerror = function (e) {
alert("Error is " + e);
}
}
function close() {
socket.close();
}
function sendMsg() {
socket.send("This is a client message ");
}
</script>
</head>
<body>
<button onclick="connect()">connect</button>
<button onclick="close()">close</button>
<button onclick="sendMsg()">sendMsg</button>
</body>
</html>
6.测试

问题:
1.这里往所有的websocket中发送消息了,需要添加一下判断。

2.可以使用提供的工具类进行测试
http://www.jsons.cn/websocket/


posted on
浙公网安备 33010602011771号