Java/Spring Framework

[ Spring ] 채팅 구현을 위한 설정 / 테스트

Mungwang 2023. 9. 4. 09:06

💎 pom.xml / servlet-context.xml 추가

📣 pom.xml

- 채팅기능을 구현할때 pom.xml에는 크게 ↓ 3개 라이브러리를 추가해주면된다.

<!-- ** jackson-databind 다운 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.14.2</version>
</dependency>
<!-- Spring WebSocket -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-websocket</artifactId>
	<version>${org.springframework-version}</version>
</dependency>
<!--Java에서 JSON을 쉽게 다룰 수 있게 해주는 구글 라이브러리 -->
<!-- GSON 라이브러리 -->
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
	<groupId>com.google.code.gson</groupId>
	<artifactId>gson</artifactId>
	<version>2.9.0</version>
</dependency>

📣 servlet-context.xml 

- pom.xml에 추가하면서 websocket이 생겼을거다 체크박스를 체크해준다.

- servlet-context.xml에 source부분에 ↓ 코드 추가

<!-- 웹소켓 처리 클래스를 bean으로 -->
	<beans:bean id="testHandler"
		class="edu.kh.project.main.model.websocket.TestWebsocketHandler" />


	<!-- 어떤 주소로 웹소켓 요청이 오면 세션을 가로챌지 지정 -->
	<websocket:handlers>
		<websocket:mapping handler="testHandler"
			path="/testSock/"/>

		<!-- 요청 클라이언트의 세션을 가로채서 WebSocketSession에 넣어주는 역할 -->
		<websocket:handshake-interceptors>
			<beans:bean
				class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
		</websocket:handshake-interceptors>

		<!-- SockJS를 이용한 웹소켓 연결 요청임을 명시 -->
		<websocket:sockjs />
	</websocket:handlers>
<beans:bean id="chatHandler"
		class="edu.kh.project.chatting.model.websocket.ChattingWebsocketHandler" />
	<websocket:handlers>
		<!-- websocket 매핑 주소 -->
		<websocket:mapping handler="chatHandler"
			path="/chattingSock" />

		<websocket:handshake-interceptors>
			<!-- interceptor : http통신에서 request, response를 가로채는 역할 handshake-interceptors 
				:Httpsession에 있는 값을 가로채서 WebSocketSession 넣어주는 역할 -->
			<beans:bean
				class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
		</websocket:handshake-interceptors>

		<websocket:sockjs />
	</websocket:handlers>


📣 TestWebsocketHandler 클래스 만들어보기

public class TestWebsocketHandler extends TextWebSocketHandler {

	// WebSocketSession : 클라이언트 - 서버간 전이중통신을 담당하는 객체
	//					  클라이언트의 세션을 가로채서 저장하고 있음

	// Set : 중복 X, 순서 X
	// synchronizedSet : 동기화된 Set 객체 반환
	// -> 멀티쓰레드( 줄 안서고 기능들이 서로 실행되려고함 )
	// 	  환경에서 스레드간의 의도치 않은 충돌을 예방하기 위해 동기화(줄세움)

	private Set<WebSocketSession> sessions
	= Collections.synchronizedSet(new HashSet<>());

	// - 클라이언트와 연결이 완료되고, 통신할 준비가 되면 실행
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		// 클라이언트 웹소켓 연결을 요청하면 session에
		// 클라이언트와의 전이중 통신을 담당하는 객체 WebSocketSession을 추가

		sessions.add(session);
	}

	// - 클라이언트로부터 텍스트 메세지를 받았을 때 실행
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		
		// payload : 통신 시 탑재된 데이터(메세지)
		System.out.println("전달 받은 내용 : " + message.getPayload());
		
		// /testSock/으로 연결된 객체를 만든 클라이언트들(sessions)
		for(WebSocketSession s : sessions) {
			s.sendMessage(message);
		}
	}

	// - 클라이언트와 연결이 종료되면 실행
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {

		// sessions에서 나간 클라이언트의 정보를 제거
		sessions.remove(session);
	}


}

 

📣 SockJS 추가

- SockJs 추가 : CDN방식으로 jsp에 추가해주면 바로사용가능함!! ** 기존에연결된 js위에 추가를 해줘야한다 **

 
    <%-- SockJS 추가 --%>
    <%-- main.js 추가 --%>
   <script src="/resources/js/main.js"></script>
 

📣 JS 

   
    // 웹소켓 테스트
    // 1. SockJS 라이브러리 추가


    // 2. SockJs를 이용해서 클라이언트용 웹소켓 객체 생성
    let testSock = new SockJS("/testSock/");

    function sendMessage(name,str){

        // 매개변수 JS객체에 저장
        let obj = {}; // 비어있는 객체
       
        obj.name = name; // 객체에 일치하는 key가 없다면 자동으로 추가
        obj.str = str;

        // console.log(obj);

        // 웹소켓 연결된 곳으로 메세지를 보냄
        testSock.send(JSON.stringify(obj));
                            // JS객체 -> JSON
    }

    // 웹소켓 객체(testSock)가 서버로 부터 전달 받은 메세지가 있을 경우
    testSock.onmessage = e =>{
        // e : 이벤트 객체
        // e.data : 전달받은 메세지(JSON)

        let obj = JSON.parse(e.data); // JSON -> JS 객체

        console.log(`보낸사람 : ${obj.name} / ${obj.str}`);


    }
 

📣 Chrome 테스트

- 일반 브라우저와 Chrome 시크릿모드로 확인해보기 ( console.log )