websocket所需pom依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>2.1.8.RELEASE</version> </dependency><dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency><dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>1.3.7</version> </dependency>
websocket接口实现类:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* 前后端交互的类实现消息的接收推送(自己发送给另一个人)
*
* @ServerEndpoint(value = "/websocket") 前端通过此URI 和后端交互,建立连接
*/
@ServerEndpoint(value = "/websocket")
@Component
public class WebSocketServer {
private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
/**
* 存放所有在线的客户端
*/
private static Map<String, Session> sessionMap = new ConcurrentHashMap<>();
/**
* 连接建立成功调用的方法
*/
/**
* websocket建立连接时调用
*
* @param session
*/
@OnOpen
public void onOpen(Session session) {
if (session == null) {
return;
}
logger.debug("创建websocket会话, 会话号: {}", session.getId());
String sessionId = session.getId();
sessionMap.put(sessionId, session);
}
private synchronized void removeOldSession(String sessionId) {
try {
Session oldSession = sessionMap.get(sessionId);
if (oldSession != null && oldSession.isOpen()) {
removeSession(sessionId);
oldSession.getBasicRemote().sendText("{\"type\":\"LOGIN_CONFLICT\"}");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* websocket 断开连接时调用
*
* @param session
*/
@OnClose
public void onClose(Session session) {
if (session == null) {
return;
}
logger.debug("websocket会话断开, 会话号: {}", session.getId());
closeSession(session);
}
/**
* websocket客戶端消息
*
* @param message
*/
@OnMessage
public void onWsMessage(String message) {
logger.info("收到websocket消息: {}", message);
}
@OnError
public void onError(Session session, Throwable error) {
logger.error("发生错误");
error.printStackTrace();
}
/**
* 服务端发送消息给客户端
*/
public void sendMessage(String message) {
Iterator<String> iterator = sessionMap.keySet().iterator();
while (iterator.hasNext()) {
String sessionId = iterator.next();
Session session = sessionMap.get(sessionId);
if (session != null && session.isOpen()) {
try {
session.getBasicRemote().sendText(message);
} catch (Exception e) {
logger.error("发送websocket消息失败, 消息: {},", message, e);
// 发送消息出现异常,终止循环
closeSession(session);
iterator.remove();
}
}
}
}
private void closeSession(Session session) {
if (session == null) {
return;
}
try {
String sessionId = session.getId();
removeSession(sessionId);
if (session.isOpen()) {
session.close();
}
} catch (IOException e) {
logger.error("关闭 websocket会话 失败, ", e);
}
}
private synchronized void removeSession(String sessionId) {
sessionMap.remove(sessionId);
}
}
websocket配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
业务类引用websocket服务:
@Autowired WebSocketServer webSocketServer;
postman测试: