프로젝트를 진행하면서 restAPI와 websocket을 병행해서 사용할 일이 생겼다.
일단 웹소켓을 터미널에서 설치해줘야한다.
npm install -g wscat
그리고 라이브러리 적용
implementation 'org.springframework.boot:spring-boot-starter-websocket'
웹 소켓 설치.
그리고 websocket메시지를 처리할 클래스를 하나 만들어 줘야한다.
@Component
@RequiredArgsConstructor
// 웹소켓 메세지를 처리하는 클래스
public class WebSoketMessageHandler extends TextWebSocketHandler {
// 사용자 id와 웹소켓 세션을 매핑하는 hashmap, 사용자와 연결된 세션 추적
HashMap<String, WebSocketSession> sessionMap = new HashMap<>();
@Override
// 연결이 성립되었을 때 호출하는 메서드
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 웹소켓 세션으로부터 사용자 id를 찾아냄
String userId = searchUserName(session);
// 세션맵에 사용자 id와 웹소켓 세션 추가
sessionMap.put(userId, session);
}
@Override
// 연결이 닫혔을 때 호출되는 메서드
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// 세션에서 사용자 id 호출
String userId = searchUserName(session);
// 세션맵에서 사용자 id 제거
sessionMap.remove(userId);
}
// 웹소켓 세션의 URI를 파싱하여 사용자 id를 추출하는 메서드
public String searchUserName(WebSocketSession session) {
// URL파싱
UriComponents uriComponents = UriComponentsBuilder.fromUriString(session.getUri().toString()).build();
// 쿼리 매개변수에 uid값을 추출, 웹소켓에 연결할 때 "uid" 파라미터를 붙여서 보내야 searchUserName 메소드가 작동
return uriComponents.getQueryParams().getFirst("uid");
}
// 주문 상태를 브로드캐스트하는 메서드
public void broadcastOrderUpdate(OrderManagementDto orderManagementDto) {
String orderUpdateMessage = convertToJson(orderManagementDto);
System.out.println("잘 될거야 :" + orderUpdateMessage);
for (WebSocketSession session : sessionMap.values()) {
try {
// 세션을 통해 메세지 전송
System.out.println("진짜 잘 보내질거야 :" + session.getId());
session.sendMessage(new TextMessage(orderUpdateMessage));
} catch (Exception e) {
e.printStackTrace();
}
}
}
// DTO 객체를 JSON 문자열로 변환하는 메서드
private String convertToJson(OrderManagementDto orderManagementDTO) {
// 실제 구현에서는 Jackson 또는 Gson 등을 사용하여 JSON 변환
try {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
return objectMapper.writeValueAsString(orderManagementDTO);
} catch (Exception e) {
e.printStackTrace();
return "{}";
}
}
}
설명은 주석으로 적어놨으니 참고하길 바란다.
websocketconfig클래스를 하나 만들어줘야한다.
웹소켓 설정을 커스텀마이징 하기 위해서이다.
@EnableWebSocket
@Configuration
@RequiredArgsConstructor
// 웹소켓 설정 커스텀마이징
public class WebsocketConfig implements WebSocketConfigurer {
// 웹소켓 메세지를 처리
private final WebSoketMessageHandler webSoketMessageHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// /orders 엔드포인트에 핸들러로 등록 후 CORS 요청 허용
registry.addHandler(webSoketMessageHandler, "/ws/orders").setAllowedOrigins("*");
}
}
난 터미널에서 웹소켓통신 테스트를 진행하였다.
wscat -c 'ws://localhost:8080/ws/orders?uid=회원아이디'
터미널에서 로그인한 유저 아이디랑 웹소켓 통신을 하기 위해 연결을 하였다.
wscat을 이용해서 테스트를 진행하였다.
// put이든 get이든 post든 알아서 설정
http://localhost:8080/api/v1/orders/create
이렇게 통신하면은 잘 보내진다.
대충 기억나는대로 끄적인거라 부족한 정보가 많다. 나머지 정보는 알아서 찾아보길 바란다.