1. 服务端的实现,我尝试了两种方式:
第一种是用“@ServerEndPoint”注解来实现,实现简单;
第二种稍显麻烦,但是可以添加拦截器在WebSocket连接建立和断开前进行一些额外操作。
不管用哪种实现方式,都需要先导入jar包(如下),其中version根据实际springboot版本选择,避免冲突
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <!-- <version>1.3.5.RELEASE</version> --> </dependency>
1.1 第一种实现方法
(1)WebSocket 业务逻辑实现。参数传递采用路径参数的方法,通过以下方式获取参数:
@ServerEndpoint("/testWebSocket/{id}/{name}")
public void onOpen(Session session, @PathParam("id") long id, @PathParam("name") String name)
import Java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;
@ServerEndpoint("/testWebSocket/{id}/{name}")
@RestController
public class TestWebSocket {
// 用来记录当前连接数的变量
private static volatile int onlineCount = 0;
// concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象
private static CopyOnWriteArraySet<TestWebSocket> webSocketSet = new CopyOnWriteArraySet<TestWebSocket>();
// 与某个客户端的连接会话,需要通过它来与客户端进行数据收发
private Session session;
private static final Logger LOGGER = LoggerFactory.getLogger(TestWebSocket.class);
@OnOpen
public void onOpen(Session session, @PathParam("id") long id, @PathParam("name") String name) throws Exception {
this.session = session;
System.out.println(this.session.getId());
webSocketSet.add(this);
LOGGER.info("Open a websocket. id={}, name={}", id, name);
}
@OnClose
public void onClose() {
webSocketSet.remove(this);
LOGGER.info("Close a websocket. ");
}
@OnMessage
public void onMessage(String message, Session session) {
LOGGER.info("Receive a message from client: " + message);
}
@OnError
public void onError(Session session, Throwable error) {
LOGGER.error("Error while websocket. ", error);
}
public void sendMessage(String message) throws Exception {
if (this.session.isOpen()) {
this.session.getBasicRemote().sendText("Send a message from server. ");
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
TestWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
TestWebSocket.onlineCount--;
}
}
(2)配置ServerEndpointExporter,配置后会自动注册所有“@ServerEndpoint”注解声明的Websocket Endpoint
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
1.2 第二种实现方法
(1)WebSocket 业务逻辑实现。参数传递采用类似GET请求的方式传递,服务端的参数在拦截器中获取之后通过attributes传递给WebSocketHandler。