Supabase로 웹사이트 3개 클론하기 (Next.js 14)를 수강하며 얻은 지식들을 정리합니다.
제가 수강중인 강의는 다음 링크에서 확인 가능해요!
Supabase RealTime
https://supabase.com/docs/guides/realtime
앞서 Supabase의 핵심 기능 중 Realtime 기능을 언급했었는데요.
사용자 입장에서는 채팅기능은 매우 기본적이면서 적은 레이턴시로 응답을 주고받는게 당연하지만
막상 이것을 구현해보려고하면 개발자 입장에서는 난감한 것이 많습니다.
Supabase의 Realtime기능은 이런 페인포인트를 해결해주는 기능이라고도 할 수 있는데요
RealTime 기능을 사용하는 것에 앞서 선수지식으로 알고가야 하는 것들을 먼저 다루어 보겠습니다.
Channel
채널은 Realtime의 기본적인 구성 요소입니다.
쉽게 생각하면 Discord, Slack 채널과 같은 채팅방이라고 생각할 수 있는데요.
Supabase의 경우 Realtime Client를 초기화할 때 이런 형태로 topic을 정의합니다.
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://<project>.supabase.co', '<your-anon-key>')
const roomOne = supabase.channel('room-one') // set your topic here
Broadcast
브로드캐스트 방식은 모든 사용자에게 동일한 데이터를 전송하는 방식입니다.
게임으로 생각해보자면 전체 채팅과 같은 기능을 구현할 때에 사용한다고도 볼 수 있을 것 같아요
Broadcast 방식은 다수의 사용자에게 정보를 빠르게 전달해야 할 때 유용합니다.
하지만, 이 방식은 사용자가 늘어날수록 서버에 부하가 증가할 수 있어요.
따라서 Broadcast 방식의 사용 빈도와 메시지의 크기를 잘 관리해야 성능 저하를 방지할 수 있습니다
Presence
Presence 방식은 현재 연결된 사용자를 실시간으로 추적하는 방식입니다.
또 한번 게임으로 쳐보자면 사용자가 온라인인지, 오프라인인지와 같은 상태변화를 추적하는 기능을 구현할 때 사용할 수 있어요
하지만 Presence는 다른 방식에 대비하여 리소스를 많이 소모할 수 있기 때문에 사용에 신중해야합니다.
Postgres Changes
postgreSQL의 change 이벤트를 받아볼 수 있는 기능입니다.
supabase가 postgreSQL 기반이다보니 postgreSQL의 이벤트를 수신하는 기능도 열어준 것으로 이해할 수 있을 것 같아요
Postgres Changes를 통해서 데이터베이스에 대한 모든 변화를 실시간으로 추적할 수 있어집니다.
그러니 이것을 통해 데이터베이스 상태의 변화에 따라 특정 행동을 트리거하는게 가능해진다는 것이죠!
이걸 활용해서 채팅 메시지가 새로 추가되었을 때 이를 자동으로 클라이언트에 반영하는 로직 같은 것을 구현할 수 있을 것입니다.
채팅을 구현하는 아이디어
앞서 전체채팅을 구현하기 위해서 브로드캐스트를 사용할 수 있다고 했습니다.
그러나 broadcast 방식을 통해 구현하게되면 여러가지 복잡도가 추가되는데요.
예를 들면 broadcast를 통해 메시지를 보낸뒤 그 메시지를 데이터베이스에 또 등록을 하는 복잡도, 브로드캐스트채널을 모두 사용하고 난뒤 채널을 닫아주어야하는 복잡도 등이 추가되기 때문입니다.
따라서 Postgres Changes를 활용하여 디비에 변화가 있을때 그 변화를 구독하는 형태로 구현을 하는 방법이 더 복잡도를 낮추는 방법이 될 수 있습니다.
그럼 Broadcast와 Presence 중에 골라야한다면?
https://supabase.com/docs/guides/realtime/concepts
Supbase Docs에서는 Broadcast와 Presence 중 선택해야한다면 Broadcast를 우선할 것을 권합니다.
이는 Presence가 근본적으로 기존 상태와 변경된 상태 간의 차이를 계산해야하기 때문인데요
따라서 최대한 Presence를 적게 사용하는 것이 리소스상 유리하다고 합니다.
소소하지만 중요한점
Supabase는 기본적으로 Database의 Realtime Options이 off이기 때문에
Realtime 기능을 사용하기 전에 realtime 기능을 먼저 활성화시켜주는 것이 필요합니다.
1:1 채팅을 구현할 때의 아이디어
export async function getAllMessages({ chatUserId }) {
const supabase = await createServerSupabaseClient();
const {
data: { session },
error,
} = await supabase.auth.getSession();
if (error || !session.user) {
throw new Error("User is not authenticated");
}
const { data, error: getMessagesError } = await supabase
.from("message")
.select("*")
.or(`receiver.eq.${chatUserId},receiver.eq.${session.user.id}`)
.or(`sender.eq.${chatUserId},sender.eq.${session.user.id}`)
.order("created_at", { ascending: true });
if (getMessagesError) {
return [];
}
return data;
}
supabase 코드는 추상화가 잘되어있어서 supabase를 잘모르더라도 물흐르듯이 읽힌다는게 좋은 것 같습니다.
해당 코드에서도 아이디어만 가져와 보면 이해가 쉬운데요
"receiver가 자기자신 혹은 상대방이거나"
"sender가 자기자신 혹은 상대방이거나"
이 두가지 조건이 모두 만족되는 경우라면 그 둘은 채팅중이라는 생각을 할 수 있습니다. (나와의 채팅이 없다는 가정하에..)
마치며
채팅 기능은 언제봐도 쓰는 입장에선 참 당연한 기능인데 구현하려고하면 머리 아픈 지점들이 많은 것 같습니다.
특히 프론트엔드 개발자는 그나마 상황이 낫지만 백엔드 개발자는 더 골치가 아픈 것 같아요
그런 복잡도를 해결해주는 Supabase가 참 고맙게 느껴지는 것 같습니다.
제가 학습하고 있는 강의는 다음 링크에서 확인하실 수 있습니다.
그러면 이제 이만 글 마치도록하겠습니다. 읽어주셔서 감사합니다!
'TIL' 카테고리의 다른 글
Supabase로 웹사이트 3개 클론하기 (Next.js 14)를 수강하며 (2) (0) | 2024.08.12 |
---|---|
Supabase로 웹사이트 3개 클론하기 (Next.js 14)를 수강하며 (1) (0) | 2024.08.12 |
javascript koans (0) | 2023.03.03 |
에라토스테네스의 체 소수 찾기 알고리즘을 자바스크립트로..? (0) | 2023.02.22 |
2.21 TIL (0) | 2023.02.21 |