웹소켓 ( Web Socket )
8_websocket 프로젝트 생성
프로젝트 버전 변경, 한글 인코딩 설정, 메이븐 프로젝트 업데이트, 이전에 만들었던 프로젝트와 /root 경로 겹치면 Servers > server.xml 에서 이전 경로 주석처리까지 진행
Spring WebSocket 라이브러리 버전 아무거나 추가 >> pom.xml 에 추가한 뒤 버전을 현재 사용 스프링 버전으로 변경해준다
데이터가 넘어올때 json 형식으로 넘어오므로 Jackson Databind 라이브러리 추가 ( 2.12.1 버전 라이브러리 추가 )
com.care.root 하위에 TestSocket.java 파일 생성하여 소켓에 대한 설정을 해줄 것임
servlet-context.xml > 하단에 Namespaces 클릭 > websocket 체크 > Source 로 이동
Namespaces 에서 websocket 활성화
servlet-context.xml 작성 >> /chat 경로로 요청하면 ts 를 바라보라는 의미!!!
TestSocket.java 클래스에서 TextWebSocketHandler 상속받기
Test.socket 에서 위 메소드 3가지 오버라이딩
afterConnectionsEstablished() : 클라이언트가 연동되면 실행
handleTextMessage() : 메세지를 받으면 실행
afterConnectionClosed() : 연결이 끊겼을 경우 실행
우선은 연결 시, 끊길 시, 메세지 받을 시 각 내용을 출력해볼 것임
HomeController.java 에 기본 경로 생성
test_socket.jsp 에 코드 작성 ( 상담사 연결 페이지를 출력하는 버튼 )
rec_data : 내용을 수신하기 위한 div
send_msg : 데이터를 보내기 위한 용도의 textarea
socket.jsp 작성
정상적으로 출력되는 것 확인
socket.jsp 에서 jquery 사용할 것이므로 CDN 값 추가
wsUri : 웹소켓 경로 설정 ( /chat 경로가 아까 servlet-context.xml 에서 설정한 경로 )
스크립트 작성
onMessage : 서버로부터 받은 값을 여기에 저장하겠다
onclose : 서버가 끊기면 작동할 로직
sendBtn 을 클릭하면 sendMessage() 함수를 실행하고 send_msg 의 값을 비워라 ( 텍스트 박스 안에 입력된 값을 비우기 )
sendMessage() 함수 정의 ( socket 으로 send_msg 의 값을 보내라 )
메세지가 들어올 경우 ( onMessage 함수 ) 와 연결이 끊길 경우 ( onClose 함수 ) 정의
접속 테스트, 메세지 전송 테스트
TestSocket.java 에 넘어온 메세지를 연결된 WebSocketSession 에게 전송한다 ( 지금은 자기 자신한테만 보내는 상태이며 제대로 값을 모든 세션에게 전송하려면 연결된 session 들을 배열에 담아서 반복문으로 돌려서 전송해야한다 )
session 을 List 로 받아 연결되면 List 에 add 로 세션 값을 저장
메세지가 들어오면 세션 값을 저장해놓은 List 를 반복문으로 돌려 메세지를 전송한다
정상적으로 모든 세션에 메세지가 전송되는 모습
HomeController.java 에서 test_socket 경로로 접속되면 session 값을 설정 >> 이 세션 값을 가져와서 유저를 나눌 것임 ( 추후에는 웹 사이트 아이디를 세션으로 설정하면 된다 )
일반 Session 의 값을 웹 소켓 session 에서 가로채서 사용하겠다는 의미
bean 에 추가한 경로 : org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor
위 작업을 진행해주지 않으면 httpsession 의 값과 websocket 의 session 의 값을 서로 다른 세션이기 때문에 httpsession 을 설정해줬다 하더라고 websocket 의 session 에서는 해당 값을 꺼내서 확인할 수 없다.
메세지가 들어올 시 WebSocketSession 의 Attribute 값을 map 에 담아 저장한 뒤 해당 map 에 설정해둔 name 키의 값을 사용해서 누가 보낸 메세지인지 출력 ( getPayload() 메소드는 현재 들어온 메세지를 출력 )
WebSocketSession 의 getAttributes() 메소드는 반환 값을 Map 형태로 돌려준다
>> 위 방식대로 진행하면 메세지를 출력할 때 A 가 입력한 메세지가 B와 C 에게 도착할 때 B와 C 는 자신이 보낸 메세지로 보이게 되므로 보낸 사람의 이름으로 메세지가 도착하는 로직이 추가로 들어가야 한다
socket.jsp 에서 엔터를 입력하면 메세지가 전송되게 설정
엔터 값 == 13