WebSocket 是一种网络通信协议,提供了在单个TCP连接上进行全双工通信的能力。这意味着客户端和服务器可以同时发送和接收数据,而不需要等待对方的回应。
Spring Boot 提供了对WebSocket的自动配置和简化的编程模型,使得在Spring Boot应用程序中集成WebSocket变得相对简单。
需要引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
创建socket配置文件
package com.ggp.test1017.config;import com.ggp.test1017.controller.ServerController;
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;@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new ServerController(), "/websocket").setAllowedOrigins("*");}public ServerController serverController() {return new ServerController();}
}
创建客户端配置
package com.ggp.test1017.controller;import javax.websocket.*;
import java.io.IOException;
import java.net.URI;@ClientEndpoint
public class ClientController {private Session session;private static volatile boolean isConnected = false;@OnOpenpublic void onOpen(Session session) {System.out.println("WebSocket 连接已经建立。");this.session = session;isConnected = true;}@OnMessagepublic void onMessage(String message, Session session) {
// 打印在客户端System.out.println(message);}@OnClosepublic void onClose() {System.out.println("WebSocket 连接已经关闭。");isConnected = false;}@OnErrorpublic void onError(Throwable t) {System.out.println("WebSocket 连接出现错误:" + t.getMessage());}public void connect(String url) throws Exception {WebSocketContainer container = ContainerProvider.getWebSocketContainer();container.connectToServer(this, new URI(url));}public void send(String message) throws IOException {if (isConnected) {session.getBasicRemote().sendText(message);} else {System.out.println("WebSocket 连接未建立,无法发送消息。");}}public void close() throws IOException {if (session != null) {session.close();}}// 添加一个方法来检查连接是否已经建立public boolean isIsConnected() {return isConnected;}
}
创建一个服务端配置
package com.ggp.test1017.controller;import org.springframework.web.socket.*;import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;@ServerEndpoint("/websocket")
public class ServerController implements WebSocketHandler {private static final Set<WebSocketSession> sessions = Collections.synchronizedSet(new HashSet<WebSocketSession>());@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);System.out.println("有新连接加入,当前连接数:" + sessions.size());}@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {String payload = message.getPayload().toString();System.out.println("收到来自 " + session.getId() + "的客户端信息: " + payload);// 将消息发送给所有客户端for (WebSocketSession s : sessions) {if (s.isOpen()) {s.sendMessage(new TextMessage("服务器收到信息。(已读) " + payload));}}System.out.println("服务器收到信息!(已读) " + payload);}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {System.out.println("传输错误:" + exception.getMessage());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {sessions.remove(session);System.out.println("连接关闭,当前连接数:" + sessions.size());}@Overridepublic boolean supportsPartialMessages() {return false;}
}
测试
启动服务 Application
创建模拟客户端
package com.ggp.test1017.controller;import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import java.net.URI;public class ClientDemo01 {public static void main(String[] args) throws Exception {ClientController client = new ClientController();String url = "ws://localhost:8080/websocket"; // 假设这是你的服务端WebSocket URL// 建立连接client.connect(url);// 发送消息client.send("666");System.out.println("66");// 等待连接建立Thread.sleep(500);client.close();}
}
运行demo,结果会在服务端控制台看到。
客户端界面显示:
服务端界面显示: