본문 바로가기
Spring

[WebSocket] 스프링 채팅 구현 (1) - 채팅 전송 및 수신

by 서피 2021. 6. 4.

준비

- 스프링 웹소켓을 이용하기 위해 스프링 버전 4 이상이 필요하다.

 

1. WebSocket, Jackson-databind 의존성 추가

pom.xml에 디펜던시를 추가한다.

<!-- https://mvnrepository.com/artifact/org.springframework/spring-websocket -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.3</version>
</dependency>

 

 

2. servlet-context.xml 설정

servlet-context.xml 파일의 Namespaces 탭에서 websocket을 체크한다.

 

 

Source 탭으로 이동하여 아래 내용을 추가한다.

<beans:bean id="chatHandler" class="com.studyus.common.handler.ChatHandler"/>
<websocket:handlers>
    <websocket:mapping handler="chatHandler" path="/chat/receive"/>
    <websocket:sockjs></websocket:sockjs>
</websocket:handlers>

각각 이름은 임의로 지정 가능하다.

class 속성값은 내가 만들 ChatHandler 클래스 파일 경로를 입력해야 한다.

path 속성값인 /chat/receive로 소켓 메세지가 전송되면, chatHandler 클래스로 보내준다는 의미이다.

 

 

 

3. web.xml 설정

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>

servlet 태그 내부에 <async-supported>true</async-supported>를 추가해준다.

다수의 클라이언트들이 동시에 정보를 보내기 위한 설정이다.

이 때, Invalid element name: - async-supported 오류가 발생할 수 있다.

서블릿 버전이 너무 낮은 경우 발생한다. 이 경우, web.xml 최상단의 버전값을 3.0으로 변경해준다.

 

 

 

4. ChatHandler 클래스

2.에서 설정한 패키지 경로에 ChatHandler 클래스를 생성한다.

public class ChatHandler extends TextWebSocketHandler {
	private List<WebSocketSession> sessionList = new ArrayList<WebSocketSession>();
	
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		sessionList.add(session);
        
        // 스프링 시큐리티 사용시 가능한 메소드
        // System.out.println(session.getPrincipal().getName() + "의 입장");
	}
	
	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage msg) throws Exception {
		for (WebSocketSession s : sessionList) {
			s.sendMessage(msg.getPayload()));
            
            // 스프링 시큐리티 사용시 가능한 메소드
            // s.sendMessage(new TextMessage(session.getPrincipal().getName() + ": " + msg.getPayload()));
		}
	}
	
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
		sessionList.remove(session);
        
        // 스프링 시큐리티 사용시 가능한 메소드
        // System.out.println(session.getPrincipal().getName() + "의 퇴장");
	}

}

afterConnectionEstablished - session이 연결된 후 실행되는 메소드

handleTextMessage - TextMessage객체가 전달되었을 때 실행되는 메소드

afterConnectionClosed - session이 종료된 후 실행되는 메소드

하나의 메세지가 모든 사람들에게 전송되어야 하므로, handleTextMessage에서 for문을 이용해 모든 session에 대해 메세지를 전송해준다.

 

 


채팅방이 없이 모두가 함께 채팅하는 전체채팅을 구현해서 정리한 후에, 채팅방을 추가해가는 과정을 추가로 정리하려고 했다.

근데 채팅방이 추가될 것을 감안하면서 코드를 짜다보니까 전체채팅을 구현하는 코드도 아니고 채팅방을 구현하는 코드도 아닌, 채팅방 기능이 있는 코드에서 일부가 빠져버린 어중간한 모양새가 되어서 바로 채팅방 기능으로 정리하였다.

[WebSocket] 스프링 채팅 구현(2) - 다수 채팅방

 

 

 

 

 

댓글