17일차

2024. 8. 13. 18:38FCB2O4

어제 채팅 삭제는 완료 했는데, 생각해보니 사용자 한 명에게서만 이루어지는 기능이 많음.

 

예를 들면 스트리밍 화면과 채팅창 동결이 사용자가 다른 페이지를 다녀온 후에도 실행되고 있어야 하는데, 사용자가 다른 페이지를 다녀오고 나면 상태가 초기화 되는 문제가 있었다.

 

이를 방지하기 위해  useEffect와 axios로 자바의 상태 메서드를 가져오는 것으로 해결했다.

 

컨트롤러에 있는 스트리밍, 채팅창 동결 관련 코드

    //채팅창 동결/재개 전환
    @MessageMapping("/chat.freezeChat")
    @SendTo("/topic/freezeChat")
    public boolean chatFreezing() {
        freezeChat = !freezeChat;
        return freezeChat;
    }

    //채팅창 동결/재개 상태 전파
    @GetMapping("/chat/freezeChat")
    public boolean getChatFreezing() {
        return freezeChat;
    }
    
    //스트리밍 시작/종료 전환
    @MessageMapping("/chat.streaming")
    @SendTo("/topic/streaming")
    public boolean streamingBegin() {
    	streamingBegin = !streamingBegin;
        return streamingBegin;
    }
    
    //스트리밍 시작/종료 상태 전파
    @GetMapping("/chat/streaming")
    public boolean getStreamingBegin() {
    	return streamingBegin;
    }

 

그 다음 WebCam.js 에서 다음 useEffect 에 구문 추가하기

    // 스트리밍 시작 버튼 활성화/비활성화 다른 사용자들에게 공유 시키기
    useEffect(() => {
        const socket = new SockJS('http://localhost:9001/ws'); // java 쪽의 서버포트 설정과 맞춰서 작성
        const client = new Client({

		//중략...
        
        
                //현재 스트리밍 상태 여부를 서버에서 가져오기
                axios.get('http://localhost:9001/chat/streaming')
                .then(res => {
                    const stream = res.data;
                    setWebCamView(stream);
                    if(stream){
                        getCamera();
                    }
                })
		// 중략...
        
    }, [webCamView]);

 

마찬가지로 LiveChat.js 에서도 다음 구문 추가

  // 서버에 요청 보내서 일반 사용자들에게 기능시행 후 결과를 전파하는 기능
  useEffect(() => {
    const socket = new SockJS('http://localhost:9001/ws'); // java 쪽의 서버포트 설정과 맞춰서 작성
    const client = new Client({

	// 중략...

        //현재 채팅창 동결 여부를 서버에서 가져오기
        axios.get('http://localhost:9001/chat/freezeChat')
        .then(res => {
            setFreezeChat(res.data);
        })
	
    // 중략...
    
  }, [freezeChat]);

 

이로써 다른 페이지를 다녀와도 스트리밍과 채팅창 동결이 유지될 수 있게 해결.

 

이제 남은 문제는 다른 사용자들에게도 채팅창 삭제를 전파하는 것.

 

원래는 채팅창 동결 기능을 그대로 사용했으나, 적용이 안되는 문제에 직면했다.

    //메시지 삭제 전환
    @MessageMapping("/chat.deleteMessage")
    @SendTo("/topic/deleteMessage")
    public boolean removeMessageSpread(@RequestBody ChatLog chatLog) {
    	forDeleteMessage = !forDeleteMessage;
    	return forDeleteMessage;
    }
    
    //삭제할 메시지 정보를 반환
    @GetMapping("/chat/deleteMessage")
    public boolean getRemoveMessageSpread() {
        return forDeleteMessage;
    }

 

그래서 차라리 메시지 내용과 시간을 다시 사용해 그것이 일치하는 것을 다른 사용자 화면에서도 삭제될 수 있도록 전파하는 것이 좋을 것 같다고 생각해 다음과 같이 변경

ChatLog forDeleteMessage = new ChatLog();

//메시지 삭제 전환
@MessageMapping("/chat.deleteMessage")
@SendTo("/topic/deleteMessage")
public ChatLog removeMessageSpread(@RequestBody ChatLog chatLog) {
    forDeleteMessage = chatLog;
    return chatLog;
}

//삭제할 메시지 정보를 반환
@GetMapping("/chat/deleteMessage")
public ChatLog getRemoveMessageSpread() {
    return forDeleteMessage;
}

 

 

이제 리액트에서 삭제 관련 전파 구문을 작성.

  useEffect(() => {
    const socket = new SockJS('http://localhost:9001/ws'); // java 쪽의 서버포트 설정과 맞춰서 작성
    const client = new Client({
      webSocketFactory: () => socket,
      connectHeaders: {},
      debug: function (str) {
        console.log('STOMP Debug:', str);
      },
      onConnect: function (frame) {
        console.log('STOMP Connected:', frame);
        setConnected(true);
	
    	// 중략...
    
        client.subscribe('/topic/deleteMessage', (response) => {
          const deletedMessage = JSON.parse(response.body);
          console.log('삭제할 메시지 : ', deletedMessage);
          if (deletedMessage && deletedMessage.msgContent && deletedMessage.msgAt) {
            setDeleteMessage(deletedMessage);
          }
        });

	//중략...
    
  }, [freezeChat]);

 

이후 useEffect에서 삭제 후 필터를 적용

 

  useEffect(() => {
    console.log("deleteMessage 값", deleteMessage);

    if (deleteMessage) {
      setMessages((prevMessages) =>
        prevMessages.filter(message =>
          !(message.content === deleteMessage.msgContent &&message.formattedTime === deleteMessage.msgAt)
        )
      );
      setDeleteMessage(null); // 삭제 후 deleteMessage 비우기
      
    }
  }, [deleteMessage]);

 

마지막으로 채팅창 삭제 핸들러와 서버를 연결 시키기

  //채팅 메시지 삭제
  const handleDeleteMessage = async ({ msgContent, msgAt }) => {
  
    await axios.delete('/chat/delete', {
      params: { 
        msgContent: msgContent, 
        msgAt: msgAt 
      }
    });

    if (stompClient) {
      stompClient.publish({
        destination: '/app/chat.deleteMessage',
        body: JSON.stringify({ msgContent, msgAt })
      });
    }
  };

 

 

이제 시현

 

삭제 전

 

삭제 후

 

메시지 삭제 연동에 성공했다.

 

이제 남은 것은 진짜로 사용자의 프로필 사진을 불러오기.

'FCB2O4' 카테고리의 다른 글

19일차  (0) 2024.08.16
18일차  (0) 2024.08.14
16일차  (0) 2024.08.12
15일차  (0) 2024.08.08
14일차  (0) 2024.08.07