10일차

2024. 8. 1. 18:44FCB2O4

오늘은 저번에 얻은 채팅 프로그램을 리액트로 변환하고자 한다.

 

먼저 백엔드 쪽에서의 설정

 

WebConfig

package b2o4.common.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*");
    }
}

 

리액트와 연결할 때 리액트의 로컬호스트3000을 받아들임을 명시하는 설정을 작성하고

 

WebSocketConfig

package b2o4.common.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("http://localhost:3000").withSockJS();
//        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
    }
}

 

엔드포인트와 메시지 발신지점을 설정

 

ChatController

package b2o4.controller;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

import b2o4.vo.ChatMessage;

@RestController
public class ChatController {

    @MessageMapping("/chat.send")
    @SendTo("/topic/messages")
    public ChatMessage send(ChatMessage message) {
        return message;
    }
}

 

컨트롤러에서 리액트와 연결할 부분을 매핑해준 후

 

리액트를 작성.

 

먼저 package.json 에서

 

{
  "name": "b2o4-frontend",
  "version": "0.1.0",
  "private": true,
  "proxy": "http://localhost:9001",
  "dependencies": {
    "@stomp/stompjs": "^7.0.0",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^13.0.0",
    "@testing-library/user-event": "^13.2.1",
    "axios": "^1.7.2",
    "bootstrap": "^5.3.3",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router-dom": "^6.25.1",
    "react-scripts": "5.0.1",
    "sockjs-client": "^1.6.1",
    "web-vitals": "^2.1.0"
  },

 

npm i @stomp/stompjs

npm i web-vitals

npm i sockjs-client

등 필요한 것들을 모두 설치 한 후

 

LiveChat

import React, { useState, useEffect } from 'react';
import { Client } from '@stomp/stompjs'; //   Client from 'stomp/stompjs'  ->   @stomp/stompjs
import SockJS from 'sockjs-client';

const LiveChat = () => {
  const [messages, setMessages] = useState([]);
  const [message, setMessage] = useState('');
  const [stompClient, setStompClient] = useState(null);
  const [connected, setConnected] = useState(false);

  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/messages', (response) => { // java 쪽의 컨트롤러(@SendTo)와 맞춰서 작성
          const newMessage = JSON.parse(response.body);
          setMessages((prevMessages) => [...prevMessages, newMessage]);
        });
      },
      onStompError: function (frame) {
        console.error('STOMP Error:', frame);
      },
      onWebSocketError: function (error) {
        console.error('웹소켓 에러:', error);
      }
    });

    client.activate();
    setStompClient(client);

    return () => {
      if (client) {
        client.deactivate();
      }
    };
  }, []);

  const sendMessage = () => {
    if (stompClient && connected && message) {
      stompClient.publish({
        destination: '/app/chat.send', //java 쪽의 컨트롤러(@MessageMapping)와 맞춰서 작성
        body: JSON.stringify({ sender: 'User', content: message })
      });
      setMessage('');
    } else if (!connected) {
      console.error('연결이 안됩니다. 관리자에 문의하세요.');
    }
  };

  return (
    <div>
      <div>
        {messages.map((msg, index) => (
          <div key={index}>
            <strong>{msg.sender}</strong>: {msg.content}
          </div>
        ))}
      </div>
      <input
        type="text"
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        disabled={!connected}
      />
      <button onClick={sendMessage} disabled={!connected}>
        Send
      </button>
      {!connected && <p>서버 연결중...</p>}
    </div>
  );
};

export default LiveChat;

 

 

이제 시현

 

 

일단은 성공

'FCB2O4' 카테고리의 다른 글

12일차  (0) 2024.08.05
11일차  (0) 2024.08.02
8일차  (0) 2024.07.30
7일차  (0) 2024.07.26
6일차  (0) 2024.07.25