-
스프링부트5.0 채팅서버 만들기 02 - 서버 세팅/채팅화면 디자인스프링/스프링부트5.0 - 채팅 2021. 10. 26. 21:16
유투버 '데어 프로그래밍'님 강의 참조
01 서버 세팅
- 모델링
@Data @Document(collection = "chat") public class Chat { @Id private String id; private String msg; private String sender; //보내는 사람 private String receiver;//받는 사람 private LocalDateTime createdAt; }
- MongoDB도 아이디를 직접 생성해 주나 Bson타입으로 자동 저장 한다. 그래서 직접 String으로 하는게 편하다.
- @Document 어노테이션으로 컬렉션을 선언 한다
- 나머지는 JPA형식과 동일
- 레파지토리 세팅
public interface ChatRepository extends ReactiveMongoRepository<Chat, String> { @Tailable //커서를 닫지않고 계속 유지 @Query("{sender:?0, receiver:?1}") Flux<Chat> mFindBySender(String sender, String receiver); }
- ReactiveMongoRepository로 상속 (나머지는 JPA와 같다)
- @Tailable - MongDB안에서 SELECT시에 데이터를 찾은 후 커서가 유지 되면서 이 어노테이션이 걸려있는 함수 내용이 끊기지않고 계속해서 받을 수 있도록 함
- @Query - JPA에서 RDBMS의 개념과 비슷하다. MongoDB용 쿼리 형식을 써서 모델링에 썻던 변수 내용을 찾을때 스는 방식
- Flux<> - 저번 강의에서 배웠던 WebFlux 내용 중 하나로 Flux 타입으로 선언시에 서버 즉 응답을 끊기지 않고 계속해서 유지 시킬 수 있다.
- 그리고 기본적으로 채팅서버의 요청은 HTTP 프로토콜 기반이 아니다. (HTTP는 비동기 처리가 되지 않는다. Stateless로써 데이터가 여러개가오면 여러개를 받아서 한번에 처리하고 끊어 버린다) 대신 SSE 프로토콜을 쓴다. 각각의 요청을 계속해서 흘러보내는 방식.
- 컨트롤러 세팅
@RequiredArgsConstructor @RestController //데이터 리턴 서버 public class ChatController { private final ChatRepository chatRepository; @GetMapping(value = "/sender/{sender}/receiver/{receiver}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<Chat> getMsg(@PathVariable String sender, @PathVariable String receiver) { return chatRepository.mFindBySender(sender, receiver) .subscribeOn(Schedulers.boundedElastic()); } @PostMapping("/chat") public Mono<Chat> setMsg(@RequestBody Chat chat){ chat.setCreatedAt(LocalDateTime.now()); return chatRepository.save(chat); } }
- @RequiredArgsConstructor - 레파지토리를 불러오기 위함
- @RestController - 데이터를 받기 위함
- @GetMapping(....) - 주소 세팅 및 데이터를 하나씩 계속해서 스트림처럼 흘려 보냄
- Flux<Chat> 타입으로 함수를 만들어서 Flux가 유지 되도록 만들고 Get 요청시에 sender/receiver를 파라미터로 받음
- .subscribeOn(Schedulers.boundedElastic()); - 다음 링크를 참고(https://devsh.tistory.com/entry/Schedulers-%EC%A0%95%EB%A6%AC)
더보기subscribeOn을 쓰면 Schedulers가 사용 가능해지고 이 둘을 통해 어느 쓰레드에서 작업이 실행될지 결정을 할 수 있으며 .boundedElastic() 은 수행 시간이 오래걸리는 작업에 대한 대안으로 최적화 되어 있음 - @PostMapping이 달린 함수는 데이터를 넣고 확인작업용(Mono는 데이터를 한개씩 한번만 리턴하는 형태, Flux는 계속해서 리턴하는 형태)
→ 포스트맨으로 테스트
DB에 잘 들어와 있다 → 웹으로 테스트
- 웹으로 테스트전에 버퍼사이즈를 바꿔줘야 한다.
너무나도 신기하다. 센더와 리시버를 번갈아가면서 바꿔도 계속해서 흐름이 끊기지 않고 데이터 요청/응답을 한다. 또한 왼쪽 상단에 동그라미가 계속 돌아가는 이유는 컨트롤러 타입이 Flux 이기 때문에 서버가 끊기지 않고 계속 도는 것.
02 화면 디자인
- VS(Visual Studio)로 진행 한다.
VS에서 폴더를 세팅 하자 - 다음 링크로 가서 파일을 받은 후 아래와 같이 세팅 (https://blog.naver.com/getinthere/222499751434)
03 채팅 화면 JS 이벤트 적용
채팅 입력을 엔터와 클릭으로 되도록 만들 예정 - chat.js
- JS 코드용 쓸만한 지식이 몇개 나온다 알고 넘어가자!
document.querySelector("#chat-send").addEventListener("click", ()=>{ alert("클릭 됨"); }) document.querySelector("#chat-outgoing-msg").addEventListener("keydown", (e)=>{ //alert("엔터 됨"); //console.log(e.keyCode); if(e.keyCode === 13){ alert("엔터!") } })
- html파일에 만들어놓은 id를 document.querySelector()로 찾은 후 이벤트를 걸면 된다.
- click은 클릭시 이벤트 발동, keydown은 키를 입력하면 발동
- 여기서 클릭은 쉽게 갈 수 있는데 키보드가 문제이다. 키보드가 입력될때마다 'e'라는 파라미터를 받아 엔터가 입력되면 어떤 코드가 찍히는지 보면 된다.
엔터는 13번 - 이제 이 코드값으로 엔터가 입력되는지 확인
- 이제 값이 입력되면 값이 화면에 뜨도록 하자
1) 입력된 값이 화면에 채팅처럼 올라오도록 해보자
document.querySelector("#chat-send").addEventListener("click", ()=>{ //alert("클릭 됨"); let chatBox = document.querySelector("#chat-box"); let chatOutgoingBox = document.createElement("div"); chatOutgoingBox.innerHTML = "안녕"; chatBox.append(chatOutgoingBox); })
- chatBox 변수 선언 후 이 변수에 chat-box 위치를 걸고
- chatOutgoingBox 변수 선언, 이 변수가 채팅 형식처럼 박스 하나씩 올라가야 하므로 엘리멘트 "div"를 만들어 선언
- innerHTML을 이용, JavaScript를 통해서 html의 content를 가져와서 그 값을 화면상에 보여주거나 직접 변경하여 보여주고
- 다시 chatBox 부분에 append를 chatOutgoingBox로 하면!
2) 입력된 값이 파랑색 채팅처럼 나오도록 해보자
function getMsg(){ return `<div class="sent_msg"> <p>Hello </p> <span class="time_date"> 11:18 | Today</span> </div>`; } document.querySelector("#chat-send").addEventListener("click", ()=>{ //alert("클릭 됨"); let chatBox = document.querySelector("#chat-box"); let chatOutgoingBox = document.createElement("div"); chatOutgoingBox.className = "outgoing_msg"; chatOutgoingBox.innerHTML = getMsg(); chatBox.append(chatOutgoingBox); })
- chatOutgoingBox.className - 클래스 내용을 바꾼다, 즉 아래와 같이 html에 설정된 'outgoing_msg' 형태로 바뀜
- 함수를 만들어서 css가 들어간 메세지 부분을 따로 만들고 이 내용을 innerHTML에 바꿔준다.
3) 이제 입력된 값이 나오도록 해보자
- input이 되는 태그의 아이디를 msgInput으로 걸고
- 이제 입력되어지는 값의 value를 함수의 파라미터로 받아서 그 입력값(파라미터)이 화면에 뿌려지도록 ${msg}로 처리
- 똑같이 innerHTML로 그 밸류 값을 뿌리면 됨
- 마지막으로 입력이 되고나면 빈값이 되도록 밸류를 ' ""; ' 로 처리
굿! ※ 함수이름을 getMsg() 에서 'getSendMsgBox()' 로 바꿀 것!
'스프링 > 스프링부트5.0 - 채팅' 카테고리의 다른 글
스프링부트5.0 채팅서버 만들기 03 - 서버 완성 (0) 2021.10.27 스프링부트5.0 채팅서버 만들기 01 - 환경 설정/몽고DB 및 스프링부트 5.0 개념 (0) 2021.10.26