
유저 페이지에서 나의 이벤트 참여가 완료 여부를 실시간으로 받아야 한다.
하지만 기존 HTTP 통신으로는 클라이언트에서의 요청 없이 서버에서 클라이언트로 메세지를 전달할 수 없다.
웹소켓으로는 양방향 통신이 가능하기 때문에 웹소켓을 이용해 통신하기로 한다.
클라이언트에서도, 서버에서도 소켓 통신을 한다고 허용해줘야 한다
pom.xml에 의존성 주입 (레거시 프로젝트)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${org.springframework-version}</version>
</dependency>
WebSocketConfig으로 설정
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket-demo")
.setAllowedOrigins("*")
.withSockJS();
}
}
메세지를 보내고 받을 Controller
@Log4j
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public String greeting(String message) throws Exception {
Thread.sleep(1000);
log.debug("서버에서 요청 받음");
return "Hello from server!" + message;
}
}
동작 흐름
/websocket-demo로 연결 요청/topic/greetings를 구독/app/hello에 메세지 보냄
import SockJS from 'sockjs-client';
import { Client } from '@stomp/stompjs';
useEffect(() => {
const socket = new SockJS(`${process.env.REACT_APP_API_BASE_URL}/websocket-demo`);
const stompClient = new Client({
webSocketFactory: () => socket,
onConnect: function (frame) {
console.log('Connected: ' + frame);
// 소켓 구독
stompClient.subscribe('/topic/greetings', (greeting) => {
const message = new TextDecoder().decode(new Uint8Array(greeting.binaryBody));
console.log('서버에서 받은 메세지: ', message);
});
// 소켓 발행
stompClient.publish({
destination: '/app/hello',
body: 'Hello WebSocket',
});
}
});
stompClient.activate();
}, []);
위 코드에서는 페이지 로딩 시 (useEffect) 소켓 구독과 발행이 함께 일어나지만 구독만 필요하거나 (서버에서 메세지를 받음) 발행만 필요하다면 (서버에 메세지를 보냄) 둘 중 하나만 하면 되겠다
→ stompJs 패키지였나 쓰고 있었는데 다른 패키지를 사용해 해결했다. 다른 해결법으로는 webpack.config.js 정의해서 net을 빼주는 방법이 있었는데 그냥 다른 모듈을 사용함

.setAllowedOrigins("*") 안 붙여줘서 CORS 에러 발생 (리액트 3000번 포트, 스프링 8080번 포트 이용하기에 처리 필요)이외에도 더 처리한 부분이 있었는데 잘.. 기억이 안 난다

추가적으로 커스텀할 부분도 많고, 작업이 많이 남아서 모두 완료하면 정리해서 포스팅을 남기고 싶다