Spring Websocket使用指南
- 首先需要一个类去实现WebSocketConfigurer, 并且指定ws的地址
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
private TextWebSocketHandler webSocketHandler;
@Autowired
WebSocketConfig(TextWebSocketHandler webSocketHandler) {
this.webSocketHandler = webSocketHandler;
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "/ws").setAllowedOrigins("*");
}
}
- 接下来需要定义一个WS请求的handler
@Slf4j
@Service
public class WebSocketHandler extends TextWebSocketHandler {
private WebSocketService webSocketService;
@Autowired
public WebSocketHandler(WebSocketService webSocketService) {
this.webSocketService = webSocketService;
}
@Override
public void afterConnectionEstablished(WebSocketSession session) {
log.info("sessionId {} established", session.getId());
webSocketService.put(session.getId(), session);
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
log.info("get message from sessionId {} with message {}", session.getId(), message);
webSocketService.onMessage(session.getId(), message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {
webSocketService.remove(session.getId());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
webSocketService.remove(session.getId());
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
- 具体实现handler中的对应策略
@Service
@Slf4j
public class WebSocketService {
private final Map<String, WsPayloadSession> sessionMap = new HashMap<>();
@Autowired
public WebSocketService(RecgAtomService recgAtomService) {
this.recgAtomService = recgAtomService;
}
public void put(String id, WebSocketSession webSocketSession) {
WsPayloadSession wsPayloadSession = new WsPayloadSession();
wsPayloadSession.setWebSocketSession(webSocketSession);
sessionMap.put(id, wsPayloadSession);
log.info("websocket connection {} open, now: {}", id, sessionMap.size());
}
public void remove(String sessionId) {
if (sessionMap.containsKey(sessionId)) {
try {
sessionMap.get(sessionId).getConcurrentWebSocketSession().close();
sessionMap.remove(sessionId);
log.info("websocket connection {} closed, now: {}", sessionId, sessionMap.size());
} catch (IOException e) {
log.error("Failed to close session {}", sessionId);
}
}
}
void onMessage(String sessionId, TextMessage message) {
if (sessionMap.containsKey(sessionId)) {
try {
WsRequestType wsRequestType = gson.fromJson(message.getPayload(), WsRequestType.class);
if (null == wsRequestType) {
throw new JsonSyntaxException("Request type of null is not supported!");
}
WsPayloadSession wsPayloadSession = sessionMap.get(sessionId);
sendMessage(sessionId, gson.toJson(wsResponse));
} catch (JsonSyntaxException e) {
log.error("Unknown wsRequestType: {}", message.getPayload(), e);
}
} else {
log.error("Websocket session {} is expired.", sessionId);
}
}
public void sendMessage(String sessionId, String message) {
TextMessage textMessage = new TextMessage(message);
}
@Data
private class WsPayloadSession {
private WebSocketSession webSocketSession;
}
}