코딩블로그
웹소켓,Spring boot로 간단한 채팅 application 구현하기 본문
웹 소켓이란?
두 프로그램 간의 메시지 교환을 위한 통신 방법 중 하나
특징
1. 양방향 통신(Full-Duplex)
- 데이터 송수신을 동시에 처리할 수 있는 통신 방법
- 클라이언트와 서버가 서로에게 원할 때 데이터를 주고받을 수 있다
- 통상적인 HTTP통신은 client가 요청을 보내는 경우에만 Server가 응답을 하는 단방향 통신
2. 실시간 네트워킹(Real Time-Networking)
- 웹 환경에서 연속된 데이터를 빠르게 노출
- ex) 채팅, 주식, 비디오 데이터
채팅 앱 구현해보기
파일 구조
├─main
│ ├─java
│ │ └─com
│ │ └─bee
│ │ └─chat
│ │ │ ChatApplication.java
│ │ │
│ │ ├─chat
│ │ │ ChatController.java
│ │ │ ChatMessage.java
│ │ │ MessageType.java
│ │ │
│ │ └─config
│ │ WebSocketConfig.java
│ │ WebSocketEventListener.java
│ │
│ └─resources
│ │ application.properties
│ │
│ ├─static
│ │ │ index.html
│ │ │
│ │ ├─css
│ │ │ main.css
│ │ │
│ │ └─js
│ │ main.js
│ │
│ └─templates
└─test
└─java
└─com
└─bee
└─chat
ChatApplicationTests.java
chatController.java
package com.bee.chat.chat;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.stereotype.Controller;
@Controller
public class ChatController {
//send Method
@MessageMapping("/chat.sendMessage")
//클라이언트가 /chat.sendMessage로 메시지를 보낼때 해당 메서드가 호출되어야 함을 나타낸다
@SendTo("/topic/public")
public ChatMessage sendMessage(
@Payload ChatMessage chatMessage
){
return chatMessage;
}
@MessageMapping("/chat.addUser")
@SendTo("/topic/public")
public ChatMessage addUser(@Payload ChatMessage chatMessage, SimpMessageHeaderAccessor headerAccessor){
//Add username in web socket session
headerAccessor.getSessionAttributes().put("username",chatMessage.getSender());
return chatMessage;
}
}
클라이언트가 /chat.sendMessage로 메시지를 보내면 해당 메시지가 /topic/public으로 브로드캐스팅 되고, 클라이언트가 /chat.addUser로 메시지를 보내면 사용자 정보가 세션에 저장되고 다른 클라이언트들에게 브로드캐스팅된다
WebSocketConfig.java
package com.bee.chat.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry){
//We want to add a new stomp endpoint
registry.addEndpoint("/ws").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry){
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
@Configuration애노테이션은 해당 클래스가 스프링의 구성 클래스임을 나타낸다.
@EnableWebSocketMessageBroker: Websocket메시지 중개인을 활성화하는 데 사용된다. 이 애노테이션을 사용하면 Spring WebSocket의 메시지 브로커가 활성화되고, 애플리케이션은 메시지 브로커를 통해 클라이언트와 통신을 할 수 있습니다.
registerStompEndpoints():메서드는 클라이언트가 websocket에 연결할 수 있는 엔드포인트를 등록한다. 여기서는 /ws경로로 websocket연결을 허용하여 withSockJS()를 사용하여 SockJS를 지원하다. SockJS는 WebSocket을 지원하지 않는 브라우저에서도 대체 수단을 통해 실시간 통신을 제공한다.
`configureMessageBroker()` 메서드는 메시지 중개인의 구성을 설정한다. `setApplicationDestinationPrefixes()` 메서드는 클라이언트에서 수신된 메시지의 애플리케이션 경로 접두사를 설정한다. 여기서는 `/app`으로 설정되어 있으므로 클라이언트가 `/app`으로 시작하는 경로로 메시지를 전송하면 메시지 핸들러에서 처리할 수 있다.
`enableSimpleBroker()` 메서드는 간단한 메시지 브로커를 활성화한다. `/topic`으로 시작하는 대상 주제를 가진 메시지를 클라이언트로 브로드캐스팅할 수 있게 한다. 클라이언트는 `/topic`으로 시작하는 주제를 구독하여 해당 주제로 전송되는 메시지를 수신할 수 있다.
즉, `WebSocketConfig` 클래스는 WebSocket 연결을 구성하고, `/ws` 엔드포인트를 통해 클라이언트의 연결을 허용하며, `/app` 경로로 시작하는 메시지를 핸들링하고, `/topic`으로 시작하는 메시지를 클라이언트로 브로드캐스팅하는 기능을 구성한다.
클라이언트 쪽은 간단한 js와 css로 구현하였기 때문에 생략하겠습니다
결과화면