POM文件中增加 websocket 的 starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
声明一个ServerEndpointExporter bean
@SpringBootApplication
public class WebServerApplication {
public static void main(String[] args) {
SpringApplication.run(WebServerApplication.class, args);
}
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
在创建一个WebSocket 服务类,此类有2个作用
- 启动时 ServerEndpointExporter 会扫描 @ServerEndpoint 注解,并且把 /ws/ 作为路径发布出去
- 有websocket会话时,创建一个WebSocketServer实例对应一个会话,非Spring管理,@Resource @Autowired 等注解不会生效。
@Component
@ServerEndpoint("/ws/")
public class WebSocketServer{
// 存储会话Session,往客户端发消息时需要用到
// key 使用何种逻辑,请自己决定,这里使用Session#Id
// 同步问题自行处理
private static final Map<String, Session> sessionMap = new HashMap<>();
@OnOpen
public void onWebSocketOpen(Session session) {
sessionMap.put(session.getId(), session);
}
@OnMessage
public void onWebSocketMessage(Session session, String message) {
// 接收到的消息
//如指令 listenProperyChange theObject thePropery
if(message.startWith("listenProperyChange ")){
//.....
bind(session.getId(), theObject , thePropery );
}
}
@OnClose
public void onWebSocketClose(Session session) {
sessionMap.remove(session.getId());
}
// 发送消息至客户端
public static void sendMessage(String sessionId, String msg) {
Session session = sessionMap.get(sessionId);
if (session == null) {
System.out.println("No session :" + sessionId);
return;
}
// 可以获取会话用户身份信息
// 注意,Http Session 超时后,getUserPrincipal()将返回 null,但 websocket的会话可能还连着
if (session.getUserPrincipal() == null) {
sendMessage(session, "Please login...");
return;
}
sendMessage(session, msg);
}
// 发送消息至客户端
public static void sendMessage(Session session, String msg) {
try {
session.getBasicRemote().sendText(msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
在页面中增加Js脚本
let socket;
function sendMessage(msg) {
socket.send(msg);
}
function initWebSocket() {
socket = new WebSocket("ws://" + location.host + "/ws/");
socket.onopen = function () {
// 连接成功后发送消息到服务器
sendMessage("listenProperyChange 793 length");
}
socket.onmessage = function (e) {
let json = JSON.parse(e.data);
// 从服务器中接收到的消息
};
socket.onclose = function () {
// 连接中断后,延时重连
toastr.info("与服务器通讯异常,3秒后重试重新连接", "通讯异常");
setTimeout(function () {
initWebSocket();
}, 3000);
}
}
$(function(){
try {
initWebSocket();
} catch (e) {
toastr.info("与服务器通讯异常", "通讯异常");
}
})