
HTTP의 한계
Ajax 등장
HTML5은 순수 웹 환경에서 실시간 양방향 통신이 가능해지게 만들었고, 이 명칭이 웹 소켓(Web Socket)입니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version> <!-- 또는 최신 안정 버전 -->
</dependency>
Gson
json 구조를 띄는 직렬화된 Data를 Java의 객체로 역직렬화, 직렬화 해주는 자바 라이브러리 입니다.
즉, JsonObject → JavaObject로 역직렬화
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
registry.addHandler(signalingSocketHandler(), "/ws/chat")
.setAllowedOrigins("*");
}
@Bean
public WebSocketHandler signalingSocketHandler() {
return new SignalWebSocketHandler();
}
}
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessage {
private String type;
private String sender;
private String receiver;
private Object data;
public void setSender(String sender) {
this.sender = sender;
}
public void newConnect(){
this.type = "new-connect";
}
public void closeConnect(){
this.type = "close-connect";
}
@Override
public String toString() {
return "Message{"+
"type='" + type +'\'' +
", sender='" + sender +'\'' +
", receiver='" + receiver +'\''+
", data='" + data +'}';
}
}
@Slf4j
@Component
public class SignalWebSocketHandler extends TextWebSocketHandler {
private final Map<String, WebSocketSession> sessionList = new ConcurrentHashMap<>();
// 웹 소켓 연결
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
log.info("[WebSocket session established]" + session.getId());
String userId = session.getId();
sessionList.put(userId, session);
ChatMessage chatMessage = ChatMessage.builder()
.sender(userId)
.receiver("all")
.build();
chatMessage.newConnect();
sessionList.values().forEach(s -> {
try{
if(s.getId().equals(userId)){
s.sendMessage(new TextMessage(chatMessage.toString()));
}
}catch (Exception e){
throw new RuntimeException(e);
}
});
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
ChatMessage chatMessage = getObject(message.getPayload());
chatMessage.setSender(session.getId());
WebSocketSession receiver = sessionList.get(chatMessage.getReceiver());
if(receiver != null && receiver.isOpen()){
receiver.sendMessage(new TextMessage(chatMessage.toString()));
log.info("[WebSocket received]" + session.getId());
}
}
private ChatMessage getObject(String textMessage){
Gson gson = new Gson();
ChatMessage message = gson.fromJson(textMessage, ChatMessage.class);
return message;
}
// 소켓 연결 종료
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String userId = session.getId();
sessionList.remove(userId);
final ChatMessage chatMessage = new ChatMessage();
chatMessage.closeConnect();
chatMessage.setSender(userId);
sessionList.values().forEach(s -> {
try {
s.sendMessage(new TextMessage(chatMessage.toString()));
}catch (Exception e){
throw new RuntimeException(e);
}
});
}
// 소켓 통신 에러
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
super.handleTransportError(session, exception);
}
}
postman 창 두개 띄워서 ws://localhost:8080/ws/chat 입력 후 Connect버튼을 눌러 두 사용자를 만들어 줍니다.
하나의 사용자에서 Message를 다른 사용자에 게 보냅니다.


4.그럼 Response에 반가워 라는 메세지가 도착했습니다.

간단하게 웹 소켓으로 채팅을 구현해보았습니다. 다음에는 채팅방을 추가하여 채팅의 고도화를 진행해보겠습니다.