본문 바로가기
About me/TIL

19일차

by pon9 2024. 11. 22.

오전~오후1: WebSocket + Java Spring 실시간 채팅 구현

TIL에 적을 거 생각안하고 구현하다가 뭘 적어야될지 모르겠다

package com.example.otl_server.controller.Chat;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic"); // 메시지를 전달할 경로
        config.setApplicationDestinationPrefixes("/app"); // 클라이언트 요청 경로
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS(); // WebSocket 엔드포인트
    }
}

백엔드는 생각보다 할 게 없었다. 프론트 공부 중인 것 같다고 하면 안 되겠지?

comment때랑 파일도 똑같고 websocketconfig 하나 더 들어갔다. 아 어노테이션도 좀 다르긴 하다.

아마 AOP 적용하고 빈 등등을 배우면 좀 어려워질것같다. 회원가입에는 aop를 적용시켜볼 생각이다.

aop는 클라이언트에 보내면 안되는 데이터들을 식별(? 잘 모른다..) 하는 기능이라 chat이랑 comment에는 안 어울린다

let stompClient = null;

function getFormatDate(date){
    let month = (1 + date.getMonth()).toString().padStart(2, '0');
    let day = date.getDate().toString().padStart(2, '0');
    let hours = date.getHours().toString().padStart(2, '0');
    let minutes = date.getMinutes().toString().padStart(2, '0');
    return `${month}-${day} ${hours}:${minutes}`;
}

// 서버에서 받은 메시지 출력
function showChat(chat) {
    // 메시지를 화면에 추가하는 로직
    console.log("받은 메시지: ", chat);

    let temp_html = `
        <ul>
            <li><img src="asset/img/anonymous.webp" alt="익명 프로필 이미지"></li>
            <li>
                <div class="chat_des">${chat.chat}</div>
                <div class="date">${getFormatDate(new Date(chat.date))}</div>
            </li>
        </ul>
        `
    $(`#chat_list`).prepend(temp_html);

}

function connect() {
    let socket = new SockJS('/ws');
    stompClient = Stomp.over(socket);

    stompClient.connect({}, (frame) => {
        console.log("연결됐음" + frame);

        stompClient.subscribe('/topic/public', (message) => {
            const chat = JSON.parse(message.body);
            console.log(message)
            console.log(message.body)
            showChat(chat);

        });
    });
}

function sendChat() {
    const chatMessage = {
        chat: $(`#chatMessage`).val(),
        date: new Date(),
    };

    stompClient.send('/app/chat.sendChat', {}, JSON.stringify(chatMessage));
    $(`#chatMessage`).val("");
}

// 메시지 보내기 버튼 클릭
document.addEventListener('DOMContentLoaded', () => {
    connect();
    document.getElementById("chatMessage").addEventListener('keydown', (event) => {
        const input = document.getElementById("chatMessage");
        if (event.key === 'Enter') {
            event.preventDefault();
            if (input.value.trim() === '') {
                alert("너 비어있잖아...");
                return;
            }
            sendChat();
        }
    });

    document.getElementById("chat_send").addEventListener('click', (event) => {
        const input = document.getElementById("chatMessage");
        if (event.key === 'Enter') {
            event.preventDefault();
            if (input.value.trim() === '') {
                alert("너 비어있잖아...");
                return;
            }
            sendChat();
        }
    });
});

이건 프론트다. 엔터키에 반응하게끔 만들었다.

getElementById랑 그냥 ${} 하는거랑 차이를 잘 모르겠다. 어쩔땐 이게 되고 저쩔땐 저게 되고 한다

 

흠 구현을 하긴 하는데 이게 잘하고있는건지 모르겠다.. 🤔 나 왜 js 서칭을 더 많이 하고 있니?

 

방향성을 확실히 하고싶어서 튜터님께 찾아갔더니, 프론트 없이 백엔드만 구현해보라고 하셨다.

이제 백엔드로만 게시판 페이지네이션 -> 동적쿼리 -> 보안 순서로 공부하면 된다. 실무에서는 api 하나당 예외가 5개가 넘는다고 그것에 대한 테스트코드도 짜보라고 하셨다.
혼자 공부할 때 보다 확실히 튜터님이 계시니까 즉문즉답이 가능해서 좋다.

일단 페이지네이션부터 프론트에 데이터를 어떻게 보내야 할지 구조를 좀 고민해봐야겠다.

 

 

오후2: 계산기 과제 피드백

튜터님께 피드백을 받았다. 앞으로 공부해야될 게 늘었다! 스레드, 프로세스, 프로그램의 차이점을 공부해보자.

history 패키지는 기능에 비해 클래스가 많이 나뉘어져있다고 해주셨다. 확실히 좀 많긴 했다 ㅋㅋ output과 interaction은 합쳐도 될 것 같다.

ㅋㅋㅋㅋㅋ 우리 조원끼리만 뭉쳐있었는데 갑자기 닭장이 됐다

 

 

오후3 ~ 저녁: cs공부

튜터님 팁 대로 스레드, 프로세스, 프로그램에 대해 살짝 읽어본 뒤 cs강의를 들었다.

병합 정렬에 대해 배웠다. 시간 복잡도가 logn으로, 버블정렬과 선택정렬이 n^2이니 훨씬 빠르고 효율적인 알고리즘이라고 볼 수 있다.

하지만 구현과정이 복잡해서 값이 많은 경우에서만 효율적이다. 값이 적은 경우 삽입정렬 같은게 더 효율적이다.

값을 왼, 오로 나누어 잘게 쪼개며 정렬하고 그렇게 나눠진 배열들을 다시 합친다.(merge)

합치는 과정에서 항상 가장 작은 값 두개를 비교하며 더 작은 값을 먼저 insert한다.

#include <stdio.h>

void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;

    int L[n1], R[n2];

    for (int i = 0; i < n1; i++) {
        L[i] = arr[left + i];
    }
    for (int j = 0; j < n2; j++) {
        R[j] = arr[mid + 1 + j];
    }

    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            i++;
        } else {
            arr[k] = R[j];
            j++;
        }
        k++;
    }

    while (i < n1) {
        arr[k] = L[i];
        i++;
        k++;
    }

    while (j < n2) {
        arr[k] = R[j];
        j++;
        k++;
    }
}

void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;

        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);

        merge(arr, left, mid, right);
    }
}

병합 정렬 알고리즘을 구현한 C언어 코드다.

 

오늘 할 것을 다 했다. 원래 heroku 이용해서 서버를 열어보려고 했는데 유료가 됐다.. 다른 사이트에서 열려고 하니 과정이 다 자동화가 되어있어서 굳이 할 필요성을 못 느꼈다.

남은 시간은 cs공부를 인강 다 보고 끝내야겠다. 앞으로 캠프에서 배울 내용들이 데이터, 메모리, 프로세스 관련이라 cs공부만큼 중요한 게 없다고 생각된다.

 

cs강의 듣다가 졸려서 구현할 api들 적어봤다.

여기다가 검색 기능까지 넣으면 될 듯? 예외처리는 회원가입 이후에 생각해야겠다.

근데 키오스크 과제도 슬슬 구조를 생각해야되는데..

'About me > TIL' 카테고리의 다른 글

18일차  (2) 2024.11.21
17일차  (1) 2024.11.20
16일차  (1) 2024.11.19