ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20. Message Websocket Broadcast방식으로 바꿔주기 2
    사이드프로젝트 2024. 7. 30. 16:28

    이어서 Edit과 Delete도 Broadcast방식으로 바꿔주겠다.

     

    // components/MessageActions.tsx

    const handleEdit = async () => {
        const text = inputRef.current.value.trim();
        if (text) {
          const edittedMessage = {
            ...actionMessage,
            text,
            is_edit: true,
          } as IMessage;
    
          optimisticUpdateMessage(edittedMessage);
    
          const { error } = await supabase
            .from("messages")
            .update({ text, is_edit: true })
            .eq("id", actionMessage?.id!);
    
          if (error) {
            toast.error(error.message);
          } else {
            toast.success("Successfully update a message");
          }
    	
        // edit *****************
          channel.send({
            type: "broadcast",
            event: "edit",	// event 이름은 edit으로 해준다.
            payload: { message: edittedMessage },
          });
    
          document.getElementById("trigger-edit")?.click();
        } else {
          // 메세지가 없을 경우 처리. Delete Alert을 띄운다.
          document.getElementById("trigger-edit")?.click();
          document.getElementById("trigger-delete")?.click();
        }
      };

     

    수정된 메세지를 받는 부분

    // components/ListMessages.tsx

    const channel = supabase
          .channel("chat-room") // room id를 넣어준다. 여기서는 채팅방이 하나만 있으므로 chat-room으로 전부 통일시킨거다.
          .on("broadcast", { event: "test" }, (payload) => {
            if (optimisticIds.includes(payload.payload.message.id)) {
              return;
            }
            addMessage(payload.payload.message);
            setNotification((current) => current + 1);
          })
          .on("broadcast", { event: "edit" }, (payload) => {	// 요기 ***********
            console.log("payload : ", payload);
            optimisticUpdateMessage(payload.payload.message);
          })
          .subscribe();

     

    크게 고친건 없다. 먼저 고치는 부분에서 event이름을 edit으로  channel에 emit해주었다.

    그리고 받는 부분에서 기존에 인서트 메세지를 받는부분에 이어서 on을 붙여주고 event이름을 edit으로 맞춰서 받아준다. 그리고 optimisticUpdate해준다.

     

    delete도 거의 비슷하다. 다만 optimistic delete에서 메세지의 id만 받고있기 때문에 id만 넘겨주고, 받는다.

    // components/MessageActions.tsx
    
    const handleDeleteMessage = async () => {
        optimisticDeleteMessage(actionMessage?.id!);
        // ************ 요기
        channel.send({
          type: "broadcast",
          event: "delete",
          payload: { id: actionMessage?.id },
        });
    
        const { data, error } = await supabase
          .from("messages")
          .delete()
          .eq("id", actionMessage?.id!); // eq는 쿼리에서 WHERE 과 같은 뜻이다. 아마도 equal을 표현한게 아닐까 추측해본다.
    
        if (error) {
          toast.error(error.message);
        } else {
          toast.success("Successfully Delete a Message");
        }
      };

     

    // components/ListMessages.tsx
    
    const channel = supabase
          .channel("chat-room") // room id를 넣어준다. 여기서는 채팅방이 하나만 있으므로 chat-room으로 전부 통일시킨거다.
          .on("broadcast", { event: "test" }, (payload) => {
            if (optimisticIds.includes(payload.payload.message.id)) {
              return;
            }
            addMessage(payload.payload.message);
            setNotification((current) => current + 1);
          })
          .on("broadcast", { event: "edit" }, (payload) => {
            console.log("payload : ", payload);
            optimisticUpdateMessage(payload.payload.message);
          })
          .on("broadcast", { event: "delete" }, (payload) => {	// 요기 ********
            console.log("payload : ", payload);
            optimisticDeleteMessage(payload.payload.id);
          })
          .subscribe();

     

    이제 수정과 삭제를 해보면 잘 되는 걸 볼 수있다.

     

     

    이제 다음으로 언제 디비에 접속해서 메세지를 인서트하거나 수정/삭제할 지 타이밍을 생각해보자.

    우선 현재 소켓으로 다 연결해놨기 때문에, 즉각적으로 메세지 표시/수정/삭제는 다 된다. 

    (물론 디비에 연결을 안하면 새로고침을 하면 다시 원래대로 돌아가긴 하지만.)

     

    그렇다면 디비와의 통신 횟수를 줄일 수 있지 않을까? 

    먼저 현재는 메세지를 입력하고 엔터를 칠때마다 디비에 인서트하는데, 이러면 통신횟수가 너무 많아지지 않을까?

    물론 디바운싱이나 쓰로틀링등의 방식도 있지만 그것보다, 예를들어 누구한명 나갈때만 저장을 한다던지 하는 식으로 하면 훨씬 줄일 수 있지 않을까?

     

    수정/삭제를 생각해보면, 이건 그대로 놔둬도 될 것 같다는 생각이다.  왜냐면 우선 입력에 비해 수정/삭제는 훨씬 횟수가 적을 것 같다는 생각이다.

    만약 아직 디비에 올라가지 않은 메세지라면 optimistic update를 통해 메세지 배열안의 것들이 각각 처리가 되고, DB에 정보가 안들어가 있다면 어차피 쿼리가 실행되지 않는다. (물론 이때 통신을 하지만)

    디비에 올라가있는 정보라면 지금있는 거랑 똑같으니 건드릴 필요가 없고.

     

    근데 또 카카오톡 단톡방같은 경우에는 자기가 들어간 시점에서 그 이전 채팅은 볼 수 가 없다. 이런것도 생각을 좀 해봐야되고, 운영적인 관점에서는 또 모든 채팅을 다 저장해야하고. 생각해야할게 은근 많다. 천천히 생각해보자.

     

    github : https://github.com/Wunhyeon/Next-Supabase-Chat/tree/16.MessageBroadcast

     

    GitHub - Wunhyeon/Next-Supabase-Chat

    Contribute to Wunhyeon/Next-Supabase-Chat development by creating an account on GitHub.

    github.com

     

    '사이드프로젝트' 카테고리의 다른 글

    supabase google 연결  (1) 2024.08.30
    19. Message WebSocket Broadcast 방식으로 바꿔주기 - 1  (1) 2024.07.30
    18. Invalid Date 버그처리  (0) 2024.07.29
    17. 앞으로 개선사항  (0) 2024.07.29
    16. 배포  (0) 2024.07.26

    댓글

Designed by Tistory.