실시간 대화형 플로팅 클라이언트 측(소켓, React Hooks 및 Plotly 사용)

12938 단어 reactgraphplotlysocket
특히 어디서부터 시작해야 할지 모르는 경우 실시간 그래프를 그리는 것이 어려워 보일 수 있습니다.
다행스럽게도 socket.io는 특히 서버가 대부분의 어려운 작업을 처리하는 경우 이를 매우 쉽게 수행할 수 있습니다...

이 기사에서는 실시간 플로팅 시스템의 클라이언트 측 구현에 대해 설명합니다. 이것은 시리즈의 두 번째 부분이므로 서버 측 구현을 읽지 않았다면 확인하십시오.

그 과정에서 몇 가지 프레임워크와 라이브러리를 사용할 것입니다. 가장 중요한 것은 다음과 같습니다.
  • 리액트

  • react-plotly.js (플롯을 기반으로 한 래퍼)
  • socket.io-client

  • 전제 조건



    먼저 create-react-app을 사용하여 개발 환경을 설정해야 합니다.

    npx create-react-app real-time-plotting
    

    그런 다음 real-time-plotting로 cd하고 필요한 몇 가지 추가 라이브러리를 설치해야 합니다.

    cd real-time-plotting
    npm install react-plotly.js plotly.js socket.io-client
    

    이제 가도 좋습니다! 다음을 사용하여 개발 서버를 시작하십시오.

    npm start
    

    소켓 연결 초기화



    클라이언트가 백엔드와 소켓 연결을 설정할 수 있는지 확인해야 합니다. 이를 위해 socket.io-client 라이브러리를 사용합니다. 또한 백엔드 URL을 env 파일에 저장하고 이를 REACT_APP_SOCKET_URL로 선언합니다.

    import { io } from "socket.io-client";
    
    const socketURL = process.env.REACT_APP_SOCKET_URL;
    const socket = io(socketURL);
    

    이제 소켓 변수가 있으므로 on connect 이벤트를 수신하고 서버에 그래프 요청을 내보낼 수 있습니다.

    socket.on("connect",()=>{
        socket.emit("ping_graph", {symbol: "ril.ns"});
    });
    

    엄청난! 이제 서버는 graph-plot라는 이벤트에 대한 그래프 데이터를 보내야 합니다(작동 방식을 알고 싶다면 서버 측 구현을 참조하십시오).

    socket.on("graph_plot", res => {
        let response = JSON.parse(res);
    });
    

    이제 그래프의 데이터가 response 변수에 저장되었습니다.
    이것을 React와 통합할 때입니다!

    React의 useEffect 및 useState 후크 사용



    처음에는 약간 위협적으로 보일 수 있지만 useState 머리를 감싸는 것은 놀라울 정도로 쉽습니다!
    상태 저장 값을 반환하는 함수와 이를 업데이트하는 함수입니다.

    React의useEffect 후크는 전체 렌더링 후 또는 특정 값이 변경될 때(배열에서 두 번째 인수로 전달하여) 특정 함수를 실행하는 데 사용됩니다.

    소켓 연결이 초기 렌더링 후에 한 번만 설정되도록 해야 하기 때문에 이것은 특히 편리할 것입니다.

    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    
    useEffect(() => {
            const socketURL = process.env.REACT_APP_SOCKET_URL;
            const socket = io(socketURL);
            socket.on("connect",()=>{
                socket.emit("ping_graph", {symbol: "ril.ns"});
            });
            socket.on("graph_plot", res => {
                if(loading===true){
                    setLoading(false);
                }
                let response = JSON.parse(res);
                response.config = {responsive: true}
                setData(response);
            });
            return () => socket.disconnect();
    }, []);
    

    보시다시피 여기에서 몇 가지 일이 발생했습니다.

    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    

    이것은 기본적으로 데이터가 초기에 loading로 설정되고 로드가 data로 전송되는 두 개의 상태 저장 변수nulltrue를 설정합니다.
    graph_plot에 대한 소켓 이벤트 리스너 내에서 두 가지 중요한 작업을 수행합니다.

    if(loading===true){
        setLoading(false);
    }
    setData(response);
    

    첫 번째 명령문은 기본적으로 처음 실행될 때 if 상태를 false로 설정하는 loading 명령문입니다.

    두 번째setData는 방금 얻은 소켓 값을 data로 지정합니다.

    마지막으로 useEffect 내부에 return 문을 추가했습니다.

    return () => socket.disconnect();
    

    이것은 정리 문으로 알려져 있으며 구성 요소가 마운트 해제될 때 소켓 연결이 닫혀 실수로 메모리 누수가 발생하지 않도록 하기 위해 수행됩니다.

    Plotly의 React Component를 사용하여 데이터 플로팅



    이것은 서버에서 얻은 데이터로 플롯을 생성하는 것만 포함하는 가장 쉬운 단계입니다.
    그것만큼 쉬운

    return (
        <div className="wrapper">
            <Plot
                {...data}
            />
        )}
        </div>
    )
    

    spread operator을 사용하여 객체로 반환된 데이터를 Plot 구성 요소의 소품으로 전달합니다.
    이제 실제로 서버에서 데이터를 다시 가져오기 전에 빈 그래프를 로드하지 않도록 하기 위해 loading 변수를 conditional operator에 대한 명령문으로 사용합니다.

    return (
        <div className="wrapper">
            {loading?(
                <p>
                    loading
                </p>
            ):(
                <Plot
                    {...data}
                />
            )}
        </div>
    )
    

    마무리



    이제 모든 것이 준비되었으므로 다음과 같이 표시됩니다.







    본문에 기본적인 스타일을 추가하고 그래프가 전체 화면을 덮도록 함




    <script id="gist-ltag"src="https://gist.github.com/Boidushya/f96acf07c1838197e5689d38fa2535d1.js"/>


    최종 결과는 다음과 같습니다





    자원



    Link to Github Repository
    Cover Photo by Tech Daily on Unsplash

    좋은 웹페이지 즐겨찾기