-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
329 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/main/java/com/example/sign/websocket/ChatController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.example.sign.websocket; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.ui.Model; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
|
||
import java.util.List; | ||
|
||
@Controller | ||
@RequiredArgsConstructor | ||
public class ChatController { | ||
private final ChatService chatService; | ||
|
||
|
||
@RequestMapping("/chat/chatList") | ||
public String chatList(Model model){ | ||
List<ChatRoom> roomList = chatService.findAllRoom(); | ||
model.addAttribute("roomList",roomList); | ||
return "chatList"; | ||
} | ||
|
||
|
||
@PostMapping("/chat/createRoom") //방을 만들었으면 해당 방으로 가야지. | ||
public String createRoom(Model model, @RequestParam("user1") String user1, @RequestParam("user2") String user2) { | ||
ChatRoom room = chatService.createRoom(user1, user2); | ||
model.addAttribute("room",room); | ||
model.addAttribute("user1",user1); | ||
model.addAttribute("user2",user2); | ||
return "chatRoom"; //만든사람이 채팅방 1빠로 들어가게 됩니다 | ||
} | ||
|
||
@GetMapping("/chat/chatRoom") | ||
public String chatRoom(Model model, @RequestParam("roomId") String roomId){ | ||
ChatRoom room = chatService.findRoomById(roomId); | ||
model.addAttribute("room",room); //현재 방에 들어오기위해서 필요한데...... 접속자 수 등등은 실시간으로 보여줘야 돼서 여기서는 못함 | ||
return "chatRoom"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.example.sign.websocket; | ||
|
||
import lombok.Getter; | ||
import lombok.Setter; | ||
|
||
@Getter | ||
@Setter | ||
public class ChatMessage { | ||
// 메시지 타입 : 입장, 채팅, 나감 | ||
public enum MessageType { | ||
ENTER, TALK,QUIT | ||
} | ||
private MessageType type; // 메시지 타입 | ||
private String roomId; // 방번호 | ||
private String sender; // 메시지 보낸사람 | ||
private String message; // 메시지 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.example.sign.websocket; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.Table; | ||
import jakarta.persistence.Transient; | ||
import lombok.*; | ||
import org.springframework.web.socket.WebSocketSession; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
@Entity | ||
@Getter | ||
@Setter | ||
public class ChatRoom { | ||
@Id | ||
private String roomId; | ||
private String user1; | ||
private String user2; | ||
@Transient | ||
private Set<WebSocketSession> sessions = new HashSet<>(); | ||
|
||
//hibernate 사용을 위한 생성자 | ||
public ChatRoom() { | ||
} | ||
|
||
@Builder | ||
public ChatRoom(String roomId, String user1, String user2) { | ||
this.roomId = roomId; | ||
this.user1 = user1; | ||
this.user2 = user2; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.example.sign.websocket; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import jakarta.annotation.PostConstruct; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.*; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Service | ||
public class ChatService { | ||
|
||
private final RoomRepository roomRepository; | ||
|
||
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 user1, String user2) { | ||
String randomId = UUID.randomUUID().toString(); | ||
ChatRoom chatRoom = ChatRoom.builder() | ||
.roomId(randomId) | ||
.user1(user1) | ||
.user2(user2) | ||
.build(); | ||
|
||
roomRepository.save(chatRoom); | ||
|
||
chatRooms.put(randomId, chatRoom); | ||
return chatRoom; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.example.sign.websocket; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface RoomRepository extends JpaRepository<ChatRoom, String> { | ||
} | ||
|
69 changes: 69 additions & 0 deletions
69
src/main/java/com/example/sign/websocket/WebSockChatHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.example.sign.websocket; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.CloseStatus; | ||
import org.springframework.web.socket.TextMessage; | ||
import org.springframework.web.socket.WebSocketSession; | ||
import org.springframework.web.socket.handler.TextWebSocketHandler; | ||
|
||
import java.io.IOException; | ||
import java.util.Set; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Component | ||
public class WebSockChatHandler extends TextWebSocketHandler { | ||
private final ObjectMapper objectMapper; | ||
private final ChatService chatService; | ||
|
||
|
||
@Override | ||
public void afterConnectionEstablished(WebSocketSession session) throws Exception { | ||
|
||
} | ||
|
||
|
||
@Override | ||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { | ||
String payload = message.getPayload(); | ||
ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class); | ||
ChatRoom room = chatService.findRoomById(chatMessage.getRoomId()); | ||
Set<WebSocketSession> sessions=room.getSessions(); //방에 있는 현재 사용자 한명이 WebsocketSession | ||
if (chatMessage.getType().equals(ChatMessage.MessageType.ENTER)) { | ||
//사용자가 방에 입장하면 Enter메세지를 보내도록 해놓음. 이건 새로운사용자가 socket 연결한 것이랑은 다름. | ||
//socket연결은 이 메세지 보내기전에 이미 되어있는 상태 | ||
sessions.add(session); | ||
chatMessage.setMessage(chatMessage.getSender() + "님이 입장했습니다."); //TALK일 경우 msg가 있을 거고, ENTER일 경우 메세지 없으니까 message set | ||
sendToEachSocket(sessions,new TextMessage(objectMapper.writeValueAsString(chatMessage)) ); | ||
}else if (chatMessage.getType().equals(ChatMessage.MessageType.QUIT)) { | ||
sessions.remove(session); | ||
chatMessage.setMessage(chatMessage.getSender() + "님이 퇴장했습니다.."); | ||
sendToEachSocket(sessions,new TextMessage(objectMapper.writeValueAsString(chatMessage)) ); | ||
}else { | ||
sendToEachSocket(sessions,message ); //입장,퇴장 아닐 때는 클라이언트로부터 온 메세지 그대로 전달. | ||
} | ||
} | ||
private void sendToEachSocket(Set<WebSocketSession> sessions, TextMessage message){ | ||
sessions.parallelStream().forEach( roomSession -> { | ||
try { | ||
roomSession.sendMessage(message); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
} | ||
|
||
|
||
|
||
@Override | ||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { | ||
//javascript에서 session.close해서 연결 끊음. 그리고 이 메소드 실행. | ||
//session은 연결 끊긴 session을 매개변수로 이거갖고 뭐 하세요.... 하고 제공해주는 것 뿐 | ||
} | ||
|
||
|
||
|
||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/example/sign/websocket/WebSockConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.example.sign.websocket; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.socket.WebSocketHandler; | ||
import org.springframework.web.socket.config.annotation.EnableWebSocket; | ||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; | ||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; | ||
|
||
@RequiredArgsConstructor | ||
@Configuration | ||
@EnableWebSocket //이게 websocket 서버로서 동작하겠다는 어노테이션 | ||
public class WebSockConfig implements WebSocketConfigurer { | ||
private final WebSocketHandler webSocketHandler; | ||
|
||
@Override | ||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { | ||
registry.addHandler(webSocketHandler, "/ws/chat").setAllowedOrigins("*"); | ||
// handler 등록, js에서 new Websocket할 때 경로 지정 | ||
//다른 url에서도 접속할 수있게(CORS방지) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Title</title> | ||
</head> | ||
<body> | ||
|
||
<form action="/chat/createRoom" method="post"> | ||
<input type="text" name="user1" placeholder="user1"> | ||
<input type="text" name="user2" placeholder="user2"> <!-- 사용자 이름 입력 필드 추가 --> | ||
<button type="submit">방 만들기</button> | ||
</form> | ||
|
||
<table> | ||
<tr th:each="room : ${roomList}"> | ||
<td> | ||
<a th:href="@{chatRoom(roomId=${room.roomId})}" th:text="${room.name}"></a> | ||
</td> | ||
</tr> | ||
</table> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<!DOCTYPE html> | ||
<html xmlns:th="http://www.thymeleaf.org"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>Title</title> | ||
</head> | ||
<body> | ||
<input type="text" placeholder="보낼 메세지를 입력하세요." class="content"> | ||
<button type="button" value="전송" class="sendBtn" onclick="sendMsg()">전송</button> | ||
<button type="button" value="방나가기" class="quit" onclick="quit()">방 나가기 </button> | ||
<div> | ||
<span>메세지</span> | ||
<div class="msgArea"></div> | ||
</div> | ||
</body> | ||
|
||
<script th:inline="javascript"> | ||
function enterRoom(socket){ | ||
var enterMsg={"type" : "ENTER","roomId":[[${room.roomId}]],"sender":"chee","msg":""}; | ||
socket.send(JSON.stringify(enterMsg)); | ||
} | ||
let socket = new WebSocket("ws://192.249.29.43:8080/ws/chat"); //ip 변경 부분 | ||
|
||
socket.onopen = function (e) { | ||
console.log('open server!') | ||
enterRoom(socket); | ||
}; | ||
socket.onclose=function(e){ | ||
console.log('disconnet'); | ||
} | ||
|
||
socket.onerror = function (e){ | ||
console.log(e); | ||
} | ||
|
||
//메세지 수신했을 때 이벤트. | ||
socket.onmessage = function (e) { | ||
console.log(e.data); | ||
let msgArea = document.querySelector('.msgArea'); | ||
let newMsg = document.createElement('div'); | ||
newMsg.innerText=e.data; | ||
msgArea.append(newMsg); | ||
} | ||
|
||
|
||
//메세지 보내기 버튼 눌렀을 떄.. | ||
function sendMsg() { | ||
let content=document.querySelector('.content').value; | ||
var talkMsg={"type" : "TALK","roomId":[[${room.roomId}]] ,"sender":"chee","msg":content}; | ||
socket.send(JSON.stringify(talkMsg)); | ||
} | ||
|
||
function quit(){ | ||
var quitMsg={"type" : "QUIT","roomId":[[${room.roomId}]] ,"sender":"chee","msg":""}; | ||
socket.send(JSON.stringify(quitMsg)); | ||
socket.close(); | ||
location.href="/chat/chatList"; | ||
} | ||
|
||
</script> | ||
|
||
</html> |