pure한(SockJS를 사용하지 않은 W3C표준 WebSocket) Spring WebSocket을 이용해서 양방통신이 가능한 채팅기능을 구현해보려고 하였으나... 어떤 이유인지 ws프로토콜 연결이 안된다... 추후에 다시 해보고.. 안되면 나중에 Java Socket 공부하면서 다시 해보도록 하겠다

 

SockJS를 사용하면 연결이 된다. (?) 

SockJS를 사용하면 http프로토콜을 이용하니까 되는것 같기도.. spring ws 버전 문제인가.. 

SockJS를 사용해서 브라우저와 서버를 연결하여 채팅기능으로서 활용이 가능한지 테스트를 해보겠다.

이번 예제는 테스트로 진행하고, 다음에 STOMP에서는 프로젝트에 적용할수 있도록 개발할 것이다.

 

 

 

dependency 추가

 

위와 같이 의존성을 추가하였다. SockJS도 맨 아래 추가~

(? 지금보니까 SockJS가 webjar이다.... 어쩐지 잘 안되어서 그냥 CDN을 추가했는데 .. ㅎㅎ;;)

 

 

Spring WebSocket을 이용하기 위해선 Configuration파일과 Handler파일이 필요하다 한개씩 알아보자.

 

WebSocketHandler.java

 

Socket의 Connect와 Disconnect, Message처리를 해주는 핸들러이다. TextWebSocketHandler 메소드를 상속받는다. 내가 사용할것이 단순한 채팅에 필요한 메세지형태이기 때문에 TextWebSocketHandler를 상속받았지만, 이미지와 같은 다른 리소스를 통신으로 받는다고 한다면 BinaryWebSocketHandler를 상속받으면 되겠다.

 

afterConnectionEstablished 는 소켓연결이 완료되었을 때 소환되는 메소드이다! 연결 잘 되었는지 session을 찍어봤다.

afterConnectionClosed 는 소켓연결이 끊겼을 때 소환되는 메소드이다! 이 역시 그냥 찍어봤다.

handleTextMessage 는 TextMessage형태로 메세지를 받아온다. 위에서 해준처리는 여러개의 세션이 연결되었을 때, (브라우저가 여러개 연결되었을때.. 즉 채팅방에 user가 여러명일 때) WebSocketSession단위로 List에 담아놓고, 그 리스트에 담겨있는 session을 for문돌리면서 연결된 모든 세션에게 메세지를 보낸다.

이는 브로드캐스팅 방식이다. 안드로이드와 같은(ios도 마찬가지) 앱에서 공지?와 같은 기능에서 자주 사용된다!!

 

이렇게 하면 현재 채팅방에 있는 모든 사람이 내가 보낸 메세지를 볼 수 있고, 또 그에 대한 답변을 모든 사람이 볼 수 있을 것이다. 다만, 아직 채팅방(RoomNum)이 구현이 안되어있기 때문에 방 별로 채팅이 아니라 연결된 모든 session에게 보내는 상황이다.

 

WebSocketConfig.java

 

웹소켓 설정파일이다. WebSocketConfigurer 인터페이스를 구현한다.

 

registerWebSocketHandlers를 오버라이딩해서 사용해야한다. 이는 사용자의 커스텀 핸들러를 사용하여 endPoint를 지정할 수 있다. setAllsetAllowedOrigins를 astarisk로 지정해주면 모든 브라우저에서 사용가능하다.

withSockJS()를 해줌으로써 SockJS를 사용하여 소켓을 만들것을 설정해주는 것이다.

 

chat.jsp

 

클라이언트가 사용할 채팅하는 페이지이다. 

아래 connect() 함수부터 보자. new SockJS()를 사용하여 아까 핸들러에서 지정해준 endPoint를 사용하여 연결을 해준다.

소켓이 열렸으면 onopen이 실행된다 (로그에 성공메세지 찍기)

 

성공적으로 연결되어 메세지를 보냈다고 치자. 그러면 onmessage에서 메세지를 받을 수 있다. event.data로 찍어봤다.

oncloseonerror. 뭐 그렇다.

 

위에 ready는 뭐냐?

준비상태가 되면 connect함수를 실행시켜서 소켓을 열어준다. 열려있는 상태에서, 클라이언트가 메세지를 입력(input형이며 id가 msg이겠지?) 하여 btnSend 버튼을 누르면? send() 함수를 이용하여 서버로 전송한다!!!

 

그러면 서버에서는 아까 위에서 본 핸들러의 handleTextMessage에서 TextMessage매개변수로 받아지는 것이다.

 

 

 

페이지를 열면 connection이 open된다. 

이때 Response Header를 보면 Connection이 upgrade로 되어 있다. 웹소켓 요청이다.

 

Response Headers

 

 

 

내가 보낸 메세지가 서버를 거쳐서~ 다시 ReceiveMessage로 잘 출력이 되는 모습이다.

 

 

 

브라우저를 한개 더 열어서 확인해보니,

서로 다른 세션이 서로의 메세지가 모두 출력되게 보면서 실시간 채팅이 가능한 모습이다.

 

 

 

 

 

이제, STOMP를 이용해서 조금은 더 가벼운 소켓채팅 기능을 프로젝트에 넣어볼 예정이다.

 

<생각해야 할것들>

1. 채팅방 구현 

2. STOMP의 Topic방식과 Queue방식

3. User개인별 소켓 DisConnect

 

+ webjar로 dependency 받는법. springio참고

'JAVA > Spring' 카테고리의 다른 글

컴포넌트 스캔 (@ComponentScan)  (0) 2021.12.17
싱글톤 패턴과 스프링 컨테이너  (0) 2021.12.15
Spring Socket에 대해 알아보자! - 1. WebSocket  (0) 2020.06.18
Spring WebSocket에 대한 내용 정리  (0) 2020.06.11
MyBatis  (0) 2020.04.21

+ Recent posts