본문 바로가기
내일배움캠프 TIL

2024-01-12 본 캠프 71일차 / 90일차 TIL (realtime chat(1))

by KMS_99 2024. 1. 15.

2024-01-12 본 캠프 71일차 / 90일차 TIL (realtime chat)

주요 진행사항

- real time chat 구성

 

supabase realtime 이용 chat 만들기 (1)

 

1. supabase dm 테이블 구성

 

dm_channels:

모든 dm 채널을 관리하는 table, supabase realtime 적용, space 단위로 filter를 적용시키기 위해 space_id 속성을 가지고 있음.

dm_messages:

모든 dm 메시지 정보를 담는 테이블, dm_id와 dm_channels가 매칭되는 항목으로 각 dm 채널마다 메시지를 가져옴.

 

2. 나에게 오는 모든 메시지 받기

채널의 모든 메시지 구독

useEffect(() => {
    const dmChannel = supabase.channel(`dm_channel_${spaceId}`);
    dmChannel
      .on(
        "postgres_changes",
        {
          event: "INSERT",
          schema: "public",
          table: "dm_messages",
          filter: `receiver_id=eq.${currentUserId}`,
        },
        getNewMessage
      )
      .subscribe();
  }, []);

- space 당 고유한 spaceId를 channel 명에 포함 시켜 고유한 채널을 생성한다.

- 생성한 채널에서는 realtime 설정을 한 table인 dm_messages의 insert 이벤트를 구독한다. 이 때 filter의 조건에 부합하는 이벤트만 구독하여 알려준다.

- 이벤트가 감지 되었을 시 getNewMessage라는 콜백함수를 실행시킨다.

 

3. 콜백함수 실행 (getNewMessage)

const [activateDmUsers, setActivateDmUsers] = useState<string[]>([]);

// 현재 세션의 유저 id가 receiver로 지정된 메시지가 도착했을 때
  const getNewMessage = (
    payload: RealtimePostgresInsertPayload<Tables<"dm_messages">>
  ) => {
    setActivateDmUsers((prev) => {
      if (prev.includes(payload.new.sender_id)) return prev;
      else return [payload.new.sender_id, ...prev];
    });
  };

 

activateDmUsers라는 state는 활성화 되어있는 채팅방을 나타내며,

sender user의 id 정보가 담겨져있다.

 

전체 채팅방을 구독하고 있는 과정에서 이미 activateDmUsers에 sender id가 등록이 되어있다면(채팅방이 활성화되었다.), 기존 값을 유지하고 만약 이 sender id가 등록이 되어있지 않다면(채팅방이 비활성화 되었다.), 등록하여 채팅방을 활성화 시킨다.