채팅 서버 만들기 3

바그다드·2023년 4월 11일
0

채팅 서버 만들기

목록 보기
3/4

chat.js 입력

const eventSource = new EventSource("http://localhost:8080/sender/pem/receiver/qkrmekem");

eventSource.onmessage = (event) => {
    console.log(1,event);
    const data = JSON.parse(event.data);
    console.log(2,data);
}

function getSendMsgBox(msg){
    return `<div class="sent_msg">
    <p>${msg}</p>
    <span class="time_date"> 11:18 | Today</span>
</div>`;
}


document.querySelector("#chat-send").addEventListener("click", () => {
    // alert("클릭됨");
    let chatBox = document.querySelector("#chat-box");
    let msgInput = document.querySelector("#chat-outgoing-msg");

    // alert(msgInput.value)

    let chatOutgoingBox = document.createElement("div");
    chatOutgoingBox.className="outgoing_msg";

    chatOutgoingBox.innerHTML=getSendMsgBox(msgInput.value);
    chatBox.append(chatOutgoingBox);
    msgInput.value="";

})

document.querySelector("#chat-outgoing-msg").addEventListener("keydown", (e) => {
    if(e.keyCode===13){
        // alert("클릭됨");
        let chatBox = document.querySelector("#chat-box");
        let msgInput = document.querySelector("#chat-outgoing-msg");

        // alert(msgInput.value)

        let chatOutgoingBox = document.createElement("div");
        chatOutgoingBox.className="outgoing_msg";

        chatOutgoingBox.innerHTML=getSendMsgBox(msgInput.value);
        chatBox.append(chatOutgoingBox);
        msgInput.value="";
    }
})
  • getMsg메서드에는 따옴표('')가 아니라 백틱(``, 숫자 1 옆에 있음)을 사용하자.
  • 그리고 다시 콘솔을 확인해보면 cors에러가 발생한다.
  • EventSource객체를 생성하여 서버에서 발생한 이벤트의 정보를 가지고 왔다.

ChatRepository 수정

  • 두 메서드에 @CrossOrigin을 붙여주자
	@CrossOrigin
    @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());
    }

    // Mono : 데이터를 한번만 리턴할 경우
    @CrossOrigin
    @PostMapping("/chat")
    public Mono<Chat> setMsg(@RequestBody Chat chat) {
        chat.setCreatedAt(LocalDateTime.now());
        return chatRepository.save(chat);
    }
  • 그리고 다시 콘솔을 확인해보면 데이터가 제대로 뜨는 것을 확인할 수 있다!!!

chat.js 수정

  • 이제 이 데이터들을 화면에 띄워보자
const eventSource = new EventSource("http://localhost:8080/sender/pem/receiver/qkrmekem");

eventSource.onmessage = (event) => {
    console.log(1,event);
    const data = JSON.parse(event.data);
    console.log(2,data);
    initMessage(data);
}

function getSendMsgBox(msg, time){
    return `<div class="sent_msg">
    <p>${msg}</p>
    <span class="time_date"> ${time} </span>
</div>`;
}

function initMessage(data){
    let chatBox = document.querySelector("#chat-box");
    let msgInput = document.querySelector("#chat-outgoing-msg");

    // alert(msgInput.value)

    let chatOutgoingBox = document.createElement("div");
    chatOutgoingBox.className="outgoing_msg";

    let md = data.createdAt.substring(5,10)
    let tm = data.createdAt.substring(11,16)
    convertTime = tm + " | " + md

    chatOutgoingBox.innerHTML=getSendMsgBox(data.msg,convertTime);
    chatBox.append(chatOutgoingBox);
    msgInput.value="";
}

function addMessage(){
    let chatBox = document.querySelector("#chat-box");
    let msgInput = document.querySelector("#chat-outgoing-msg");

    // alert(msgInput.value)

    let chatOutgoingBox = document.createElement("div");
    chatOutgoingBox.className="outgoing_msg";

    let date = new Date();
    let now = date.getHours()+":"+date.getMinutes()+"|"+date.getMonth()+"-"+date.getDate();

    chatOutgoingBox.innerHTML=getSendMsgBox(msgInput.value, now);
    chatBox.append(chatOutgoingBox);
    msgInput.value="";
}

document.querySelector("#chat-send").addEventListener("click", () => {
    // alert("클릭됨");
    addMessage();

})

document.querySelector("#chat-outgoing-msg").addEventListener("keydown", (e) => {
    if(e.keyCode===13){
        addMessage();
    }
})
  • 기존 데이터들을 띄우기 위한 initMessage메서드를 추가하였고, 서버에서 받아온 data값을 getSendMsgBox에 전달하여 화면에 띄웠다.
  • 이제 브라우저에서 메세지를 입력하면 서버로 보내는 기능을 구현해보자

chat.js 수정

  • addMessage를 수정해주자
// await로 이 메서드가 종료되지 않는다면 다른 메서드들도 완료가 되지 않기 떄문에 비동기 메서드로 바꿔줌
async function addMessage(){ 
    let chatBox = document.querySelector("#chat-box");
    let msgInput = document.querySelector("#chat-outgoing-msg");

    // alert(msgInput.value)

    let chatOutgoingBox = document.createElement("div");
    chatOutgoingBox.className="outgoing_msg";

    let date = new Date();
    let now = date.getHours()+":"+date.getMinutes()+"|"+date.getMonth()+"-"+date.getDate();

    let chat = {
        sender : 'pem',
        receiver : "qkrmekem",
        msg: msgInput.value
    };
	
    // 통신에 시간이 걸리므로 await를 걸어 대기하게 해줌
    let response = await fetch("http://localhost:8080/chat",{ 
        method:"post",
        body: JSON.stringify(chat), // js -> json으로 변환
        headers:{
            "Content-Type":"application/json;charset=utf-8"
        }
    });

    //console.log(response);
	
    // 여기도 마찬가지로 파싱하는데 시간이 걸리므로 await를 걸어줌
    let parseResponse = await response.json();
    console.log(parseResponse);

    chatOutgoingBox.innerHTML=getSendMsgBox(msgInput.value, now);
    chatBox.append(chatOutgoingBox);
    msgInput.value="";
}
  • fetch는 api를 호출하는 메서드로 첫번째 인자로는 url정보를 받고, 두번째 인자로는 옵션 객체를 받는데, 위에서는 post메서드를 사용할 것이므로 메서드, http헤더, http바디 정보를 보내자.
    또한 통신에 시간이 걸리는데 js는 코드를 읽을 때 통신등으로 인해 시간이 걸리게 되면 변수 안에 null을 넣고 다름 코드를 읽기 때문에 통신이 완료 될때까지 await를 걸어줘야 한다.
    - await를 걸게 되면 처리가 끝날 때까지 다른 메서드를 읽지 못하므로 function 앞에 async를 붙여 비동기 메서드로 수정을 해주자.
  • http바디에는 채팅에 대한 정보를 객체로 담아 json형식으로 파싱해서 보낸다.
  • fetch는 api호출이 성공하면 응답 객체를, 실패하면 에러 객체를 리턴하는데 이를 response라는 변수에 담아주고, 이 변수는 다시 json형식으로 파싱하여 화면에 띄워주자.
  • 웹에서는 파일의 확장자는 별 의미가 없으므로 데이터를 보낼때 확실하게 설정을 해줘야 하는데 이는 MIME타입을 확인하자MIME타입


  • 이제 메세지를 보낼 때마다 화면에 반영되고 db에도 정상적으로 메세지가 저장되는 것을 확인할 수 있다!!!
profile
꾸준히 하자!

0개의 댓글