- 首先获取消息的内容,即payload。
- 将payload转换为JSONObject对象,并从中获取消息类型type。
- 如果消息类型是"join",则从消息中获取群组ID,并将当前WebSocketSession的ID加入到该群组对应的Set中。
- 如果消息类型是"leave",则从消息中获取群组ID,并从该群组对应的Set中移除当前WebSocketSession的ID。
- 如果消息类型是"message",则从消息中获取群组ID,并获取该群组对应的所有WebSocketSession,逐一向这些Session发送消息。
其中,groups和sessions是两个Map,分别用来存储群组与其对应的WebSocketSessions。computeIfAbsent和computeIfPresent方法分别用来向Map中添加元素和更新元素。sendMessage方法用来向客户端发送消息。
导入依赖
<!-- spring-boot-starter-websocket依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
创建MyWebSocketHandler类
import com.songzixain.service.MyWebSocketHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** <p>* Description: WebSocketConfig配置类* </p>** @author * @version * @create * @see */@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new MyWebSocketHandler(), "/ws").setAllowedOrigins("*");
创建MyWebSocketHandler类
这段代码是一个WebSocket处理器中的消息处理方法,用来处理WebSocket客户端发送的消息
/*** <p>* Description: MyWebSocketHandler用 来处理WebSocket客户端发送的消息* </p>** @author * @version * @create * @see */
@Slf4j
public class MyWebSocketHandler implements WebSocketHandler {private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();private static final Map<String, Set<String>> groups = new ConcurrentHashMap<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.put(session.getId(), session);}@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {String payload = message.getPayload().toString();log.info("接收到的用户消息 {}", payload);JSONObject json = JSON.parseObject(payload);String type = json.getString("type");// 用户加入了群组if ("join".equals(type)) {String groupId = json.getString("groupId");groups.computeIfAbsent(groupId, k -> new HashSet<>()).add(session.getId());} else if ("leave".equals(type)) {String groupId = json.getString("groupId");groups.computeIfPresent(groupId, (k, v) -> {v.remove(session.getId());return v;});// 接收到了用户消息} else if ("message".equals(type)) {String groupId = json.getString("groupId");Set<String> groupSessions = groups.get(groupId);for (String sessionId : groupSessions) {WebSocketSession s = sessions.get(sessionId);if (s != null && s.isOpen()) {s.sendMessage(new TextMessage(payload));}}}}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {sessions.remove(session.getId());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {sessions.remove(session.getId());groups.values().forEach(v -> v.remove(session.getId()));}@Overridepublic boolean supportsPartialMessages() {return false;}
}
前端的html测试页面
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>WebSocket Chat</title>
</head>
<body><div id="output"></div><input id="input" type="text" placeholder="Type your message"><button id="send">Send</button><button id="join">Join Group</button><button id="leave">Leave Group</button><script>var socket = new WebSocket("ws://localhost:8080/ws");socket.onopen = function(event) {console.log("WebSocket connected");};socket.onmessage = function(event) {var message = event.data;var output = document.getElementById("output");var p = document.createElement("p");p.innerText = message;output.appendChild(p);};socket.onclose = function(event) {console.log("WebSocket disconnected");};var sendButton = document.getElementById("send");var input = document.getElementById("input");var joinButton = document.getElementById("join");var leaveButton = document.getElementById("leave");sendButton.addEventListener("click", function() {var message = {userId: "1",type: "message",groupId: "group1",content: input.value};socket.send(JSON.stringify(message));input.value = "";});joinButton.addEventListener("click", function() {var message = {userId: "1",type: "join",groupId: "group1"};socket.send(JSON.stringify(message));});leaveButton.addEventListener("click", function() {var message = {userId: "1",type: "leave",groupId: "group1"};socket.send(JSON.stringify(message));});socket.onmessage = function(event) {var message = event.data;var output = document.getElementById("output");var p = document.createElement("p");p.innerText = message;output.appendChild(p);
};</script>
</body>
</html>
这个WebSocket处理器实现了群聊功能,并支持用户加入和离开群组时向群组中的其他用户发送通知。
启动Spring Boot项目.点击加入群主,然后就可以发送消息了