728x90
반응형
SMALL
package com.test.sbp.config;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.*;
import org.springframework.web.socket.server.HandshakeInterceptor;
import java.util.Map;
//@Configuration
//@EnableWebSocketMessageBroker //STOMP를 사용하기 위한 어노테이션 //@EnableWebSocket : 기본적인 웹소켓 사용을 위한 어노테이션
//public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
//
// @Override //TODO:property 분리
// public void configureMessageBroker(MessageBrokerRegistry registry) {
// registry.setApplicationDestinationPrefixes("/pub") //서버에서 클라이언트로부터의 메서지를 받을 api의 prefix설정, 아래topic러는 곳에 구독하면, 실제경로는 "topic/pub"
// .enableStompBrokerRelay("/topic") //SimpleBroker의 기능과 외부 message broker(RabbitMQ, ActiveMQ 등)에 메시지를 전달하는 기능을 가지고 있다.
// .setRelayHost("localhost") // 여기부터 외부브로커인 RabbitMQ를 사용하기위한 설정.
// .setVirtualHost("/")
// .setRelayPort(61613)
// .setClientLogin("guest")
// .setClientPasscode("guest");
// }
//
// @Override
// public void registerStompEndpoints(StompEndpointRegistry registry) {
// registry.addEndpoint("/ws") //엔드포인트는 /ws
// .setAllowedOrigins("*");
// }
//}
@RequiredArgsConstructor
@Configuration
@EnableWebSocket
public class WebSockConfig implements WebSocketConfigurer {
private final WebSocketHandler webSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "ws/chat").setAllowedOrigins("*");
}
}
package com.test.sbp;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.sbp.dto.ChatMessage;
import com.test.sbp.dto.ChatRoom;
import com.test.sbp.service.ChatService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
@Slf4j
@RequiredArgsConstructor
@Component
public class WebSocketHandler extends TextWebSocketHandler {
private final ObjectMapper objectMapper;
private final ChatService chatService;
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
log.info("{}", payload);
ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class);
ChatRoom chatRoom = chatService.findRoomById(chatMessage.getRoomId());
chatRoom.handlerActions(session, chatMessage, chatService);
}
}
package com.test.sbp.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ChatMessage {
// 메시지 타입 : 입장, 채팅
public enum MessageType {
ENTER, TALK
}
private MessageType type; // 메시지 타입
private String roomId; // 방번호
private String sender; // 메시지 보낸사람
private String message; // 메시지
}
package com.test.sbp.dto;
import com.test.sbp.service.ChatService;
import lombok.Builder;
import lombok.Getter;
import org.springframework.web.socket.WebSocketSession;
import java.util.HashSet;
import java.util.Set;
@Getter
public class ChatRoom {
private String roomId;
private String name;
private Set<WebSocketSession> sessions = new HashSet<>();
@Builder
public ChatRoom(String roomId, String name) {
this.roomId = roomId;
this.name = name;
}
public void handlerActions(WebSocketSession session, ChatMessage chatMessage, ChatService chatService) {
if (chatMessage.getType().equals(ChatMessage.MessageType.ENTER)) {
sessions.add(session);
chatMessage.setMessage(chatMessage.getSender() + "님이 입장했습니다.");
}
sendMessage(chatMessage, chatService);
}
private <T> void sendMessage(T message, ChatService chatService) {
sessions.parallelStream()
.forEach(session -> chatService.sendMessage(session, message));
}
}
package com.test.sbp.controller;
import com.test.sbp.dto.ChatRoom;
import com.test.sbp.service.ChatService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequiredArgsConstructor
@RestController
@RequestMapping("/chat")
public class ChatController {
private final ChatService chatService;
@PostMapping
public ChatRoom createRoom(@RequestBody String name) {
return chatService.createRoom(name);
}
@GetMapping
public List<ChatRoom> findAllRoom() {
return chatService.findAllRoom();
}
}
package com.test.sbp.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.sbp.dto.ChatRoom;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.*;
@Slf4j
@RequiredArgsConstructor
@Service
public class ChatService {
private final ObjectMapper objectMapper;
private Map<String, ChatRoom> chatRooms;
@PostConstruct
private void init() {
chatRooms = new LinkedHashMap<>();
}
public List<ChatRoom> findAllRoom() {
return new ArrayList<>(chatRooms.values());
}
public ChatRoom findRoomById(String roomId) {
return chatRooms.get(roomId);
}
public ChatRoom createRoom(String name) {
String randomId = UUID.randomUUID().toString();
ChatRoom chatRoom = ChatRoom.builder()
.roomId(randomId)
.name(name)
.build();
chatRooms.put(randomId, chatRoom);
return chatRoom;
}
public <T> void sendMessage(WebSocketSession session, T message) {
try{
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message)));
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
728x90
반응형
LIST
'개발 > Spring' 카테고리의 다른 글
웹소캣 1:1 채팅방 (수정전) (0) | 2023.04.09 |
---|---|
웹소켓 알림 메세지 - session (0) | 2023.04.09 |
yml 파일이란 ? (0) | 2023.03.12 |
WebSock 구현 (0) | 2023.03.07 |
JWT 장점과 단점 (0) | 2023.02.15 |