WebSocketConfig.java
@RequiredArgsConstructor
@Configuration
@EnableWebSocket
public class WebSockConfig implements WebSocketConfigurer {
private final WebSocketHandler webSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "/ws/design-file").setAllowedOrigins("*");
}
}
WebSocketHandler.java
/**
* 웹소켓 클라이언트로부터 채팅 메시지를 전달받아 채팅 메시지 객체로 변환
* 전달받은 메시지에 담긴 채팅방 Id로 발송 대상 채팅방 정보를 조회함
* 해당 채팅방에 입장해있는 모든 클라이언트들(Websocket session)에게 타입에 따른 메시지 발송
*/
@Slf4j
@RequiredArgsConstructor
@Component
public class WebSockChatHandler 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 {}", payload);
ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class);
ChatRoomDto room = chatService.findRoomById(chatMessage.getRoomId());
room.handleTempActions(session, chatMessage, chatService);
}
}
String payload = message.getPayload();
log.info("payload {}", payload);
=> 클라이언트가 보낸 요청을 로그에 찍히게 해준다.
SocketService.java
@Slf4j
@RequiredArgsConstructor
@Service
public class ChatService {
private final ObjectMapper objectMapper;
private Map<String, ChatRoomDto> chatRooms;
@PostConstruct
private void init() {
chatRooms = new LinkedHashMap<>();
}
public List<ChatRoomDto> findAllRoom() {
return new ArrayList<>(chatRooms.values());
}
public ChatRoomDto findRoomById(String roomId) {
return chatRooms.get(roomId);
}
public ChatRoomDto createRoom() {
String randomId = UUID.randomUUID().toString();
ChatRoomDto chatRoom = ChatRoomDto.builder()
.roomId(randomId)
.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);
}
}
}
ChatMessage.java
@Getter
@Setter
public class ChatMessage {
// 메시지 타입 : 입장, 채팅
public enum MessageType {
ENTER, ENTER2
}
private MessageType type; // 메시지 타입
private String roomId; // 방번호
private String message; // 메시지
}
ChatRoomDto.java
@Getter
public class ChatRoomDto {
private String roomId;
private Set<WebSocketSession> sessions = new HashSet<>();
@Builder
public ChatRoomDto(String roomId) {
this.roomId = roomId;
}
public void handleTempActions(WebSocketSession session, ChatMessage chatMessage, ChatService chatService) throws ParseException {
if (chatMessage.getType().equals(ChatMessage.MessageType.ENTER)
//메세지 타입이 enter 라면 보내줄 것) {
sessions.add(session);
//보낼 메세지를 set해주는 과정
chatMessage.setMessage(
jsonText.MatchjsonTest()
);
sendMessage(chatMessage, chatService);
}
if
(chatMessage.getType().equals(ChatMessage.MessageType.ENTER2)
//메세지 타입이 enter2라면 보내줄 것) {
sessions.add(session);
chatMessage.setMessage(
jsonText.UnMatchjsonTest()
);
sendMessage(chatMessage, chatService);
}
}
public <T> void sendMessage(T message, ChatService chatService) {
sessions.parallelStream().forEach(session -> chatService.sendMessage(session, message));
}
}
로컬
ws://localhost:8081/ws/design-file
서버
wss://홈페이지 주소(ssl 적용된 https)/ws/design-file
소켓 구현 출처 : https://daddyprogrammer.org/