오전~오후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들 적어봤다.
여기다가 검색 기능까지 넣으면 될 듯? 예외처리는 회원가입 이후에 생각해야겠다.
근데 키오스크 과제도 슬슬 구조를 생각해야되는데..