사용자가 www.google.com을 브라우저의 주소창에 입력 하면 브라우저는 사용자가 입력한 문자열을 분석해서 이 URL이 웹사이트 요청인지 검색어인지를 구분합니다. 만약 http://또는 https://가 생략되었다면 자동으로 추가됩니다.
2. DNS조회
브라우저, 운영체제 또는 로컬 네트워크에 www.google.com의 IP 주소가 캐시되어 있는지 확인합니다. 캐시가 없다면 ISP(인터넷 서비스 제공자)의 DNS서버에 도메인 이름을 요청합니다. DNS서버는 최종적으로 www.google.com에 해당하는 IP주소를 반환합니다.
브라우저는 반환받은 IP주소와 통신하기 위해 TCP연결을 시작합니다. 클라이언트가 서버에 연결요청(SYN)을 보내고 서버는 요청을 승인하고 클라이언트는 연결확인을 보내고 연결을 완료합니다.
TCP는 또 뭔데.. ?
" TCP(Transmission Control Protocol)은 컴퓨터 간에 데이터를 안전하게 전송하기 위한 다중화 프로토콜이다. 한국어로는 전송제어 프로토콜이라고도 한다. TCP의 역할은 두 호스트를 연결하고 데이터 스트림을 교환하게 하고 한 컴퓨터에서 다른 컴퓨터로 전송되는 모든 데이터가 오류나 결함 없이 올바른 순서로 성공적으로 수신되도록 하게 한다. "
여기서도 먼저 구독을 해야한다. 여기서 사용된 pusherKey는 사용자 이메일을 기반으로 생성고 개인화된 채널 역할을 한다. 이를 통해 자신과 관련된 실시간 이벤트를 받는다.
Pusher 이벤트 핸들러
pusher를 통해 서버에서 특정 이벤트를 클라이언트로 보낼때 그 이벤트를 처리하기 위한 핸들러를 설정한다.
새로운 대화가 추가될때
const newHandler = (conversation: FullConversationType) => {
setItems((current) => {
if (find(current, { id: conversation.id })) {
return current; // 이미 존재하는 대화면 그대로 유지
}
return [conversation, ...current]; // 새로운 대화를 맨 앞에 추가
});
};
- 새로운 대화가 생성되었을 때 이를 items 상태에 추가한다.
- find함수로 이미 동일한 conversation.id가 있는지 확인하고, 없다면 새로운 대화를 추가한다.
기존 대화가 업데이트될 때
const updateHandler = (conversation: FullConversationType) => {
setItems((current) =>
current.map((currentConversation) => {
if (currentConversation.id === conversation.id) {
return {
...currentConversation,
messages: conversation.messages, // 메시지 업데이트
};
}
return currentConversation; // 다른 대화는 그대로 유지
})
);
};
- 대화의 메시지가 변경될 경우 이를 상태에 반영한다.
- 해당 대화의 id를 기준으로 업데이트 된 내용을 상태에 적용한다.
대화가 삭제될 때
const removeHandler = (conversation: FullConversationType) => {
setItems((current) => {
return [...current.filter((convo) => convo.id !== conversation.id)]; // 삭제된 대화 제거
});
if (conversationId === conversation.id) {
router.push("/conversations"); // 현재 보고 있는 대화라면 대화 목록 페이지로 이동
}
};
- 대화가 삭제되었을 대 이를 items상태에서 제거한다.
- 현재 열려있는 대화가 삭제된 대화와 동일하다면, 사용자를 대화 목록 페이지로 리다이렉트한다.
- prop으로 src, isopen, onclose가 전달되고 대화창 내에서 이미지를 클릭하면
모달이 열린다.
Loading Modal
Loading Modal 컴포넌트는 사용자가 작업을 기다리는 동안 화면에 로딩 상태를 표시하기 위해 설계된 로딩 모달 컴포넌트이다. 이 컴포넌트는 Dialog와 Transition을 사용하여 모달의 애니메이션과 상태 관리를 구현하며, 로딩 스피너로 react-spinners의 ClipLoader를 활용한다.
이 로딩 모달은 conversation과 user폴더에 위치 시켰다.
지금쯤 내용이진행되니 전체적인 흐름이 이해가 되는것 같다. 대신 더 디테일한 이해들이 필요할 것으로 느껴지는 부분들이 있다고 느껴진다.
const onDelete = useCallback(() => {
setIsLoading(true);
axios
.delete(`/api/conversations/${conversationId}`) // 서버로 DELETE 요청 전송
.then(() => {
onClose(); // 모달 닫기
router.push("/conversations"); // 대화 목록 페이지로 이동
router.refresh(); // 대화 목록 새로고침
})
.catch(() => toast.error("something went wrong!")) // 에러 메시지 표시
.finally(() => setIsLoading(false)); // 로딩 상태 종료
}, [conversationId, router, onClose]);
- axios.delete: 서버 API를 호출하여 대화를 시작한다.
- 성공하게되면 onClose를 통해 모달을 닫고 router.push로 conversations페이지로 이동한다. 그 이후에 router.refresh로 대화 목록을 새로고침하여 변경사항을 반영한다.
- 실패시에는 toast.error를 통해 에러 메시지를 사용자에게 표시한다.
- 작업 완료 후에는 setIsLoading(false) 로딩 상태를 종료한다.
==> confirmModal은 사용자로 하여금 중요한 작업을 신중히 수행하도록 돕는 모달 컴포넌트이다. React상태관리, Next.js라우팅, axios를 통한 비동기 요청 등 다양한 기술 스택이 조화를 이루며 완성도 높은 UX를 제공한다.
Modal 컴포넌트
이 코드는 React와 headlessui/react를 사용하여 모달 창을 구현한 Modal컴포넌트이다. 이 컴포넌트는 재사용 가능한 모달창으로 children프로퍼티를 통해 원하는 내용을 동적으로 렌더링 할 수 있으며, 열기와 닫기 상태를 관리할 수 있도록 설계되어 있다.
이 컴포넌트에서는 UI만 구성되어 있다.
이렇게 사용자를 삭제할 수 있는 모달을 만드는 것을 완성했다.
SettingsModal
그리고 만든게 settingsmodal이다. 이건 개인의 프로필이나 이름 등을 교체할 수 있는 모달이다.
이 코드는 데이터베이스에서 현재 사용자가 참여하고 있는 대화목록을 가져오는 함수이다. prisma를 사용해 대화 데이터와 관련도니 사용자 및 메시지 정보를 포함하여 반환한다. getConversations함수는 대화 목록을 시간순으로 정렬하여 반환하며 에러가 발생하면 빈 배여을 반환한다.
- 이 handleclick은 사용자가 특정 Userbox를 클릭했을 때 실행되는 클릭핸들러이다.
이 함수는 클릭 이벤트에 반응하여 새로운 대화를 생성하고 해당 대화 화면으로 이동하는 역할을 한다.
- axios.post(...) : 사용자가 Userbox를 클릭하면 해당 사용자의 ID를 포함한 POST요청을 서버 /api/conversations 엔드포인트로 보낸다. 이 요청의 목적은 선택된 사용자와의 새로운 대화를 생성하거나 이미 존재하는 대화를 가져오는 것이다.
- 대화 화면으로 이동 data.data.id.를 사용하여 router.push를 호출한다. router.push는 Next.js의 클라이언트 측 라우팅 기능을 활용하여 생성된 대화의 상세 페이지로 이동한다.
nextauth.js는 next.js애플리케이션에서 인증을 쉽게 구현할 수 있도록 해주는 오픈소스 라이브러리이다. OAuth, 이메일, 자격증명(credentials)등을 통해 사용자를 인증할 수 있으며, 인증세션을 관리하는 기능을 제공한다. Next.js의 API Routes와 긴밀하게 통합되어 서버리스 환경에서도 원활하게 작동한다.
NextAuth.js의 주요 구성 요소
Providers (인증 제공자) NextAuth.js는 다양한 인증 제공자(OAuth 제공자)를 지원한다.
예: Google, GitHub, Facebook, Twitter 등
또한, 자체 자격 증명(Credentials Provider)을 설정하여 커스텀 로그인 방식을 구현할 수도 있다.
Session (세션 관리) 사용자가 로그인하면 세션이 생성된다. 이 세션은 쿠키를 통해 클라이언트와 서버 간에 유지되며, 사용자의 로그인 상태를 확인하는 데 사용된다.
Callbacks (콜백) 로그인, 세션, JWT 등과 관련된 다양한 작업을 커스터마이징할 수 있도록 콜백 함수를 제공한다.
Adapters 사용자의 데이터를 데이터베이스에 저장하거나 읽어오는 작업을 처리한다. 예를 들어, MongoDB, PostgreSQL, MySQL 등을 지원한다.
NextAuth.js를 이용한 로그인 인증 방식
NextAuth 설정 파일 생성 ([...nextauth].ts) pages/api/auth/[...nextauth].ts 또는 app/api/auth/[...nextauth]/route.ts 파일에서 인증 설정을 정의합니다. 주요 설정은 다음과 같습니다.