[Node.js] 웹소켓에서 데이터를 받아오는 문제

조회수 647회

안녕하세요.

현재 웹소켓 데이터를 받아오는데 문제가 있어서 이렇게 글을 올립니다.

var ws = new WebSocket(`wss://${host}:${port}`);
var api = new api_call(ws);

function get_data(today){
    api_call.on('ready', () => {
        api_call.send({
            or_ordr_dt: today  // 오늘 날짜
        });
    });
    api_call.on('getData', (data) => { 
        console.log(JSON.stringify(data)); 
    });
};

get_data('20180830');

소켓에 위의 코드가 제공받은 api의 기본 구조인데 .send를 보낼 때만 데이터를 줍니다.

프로그램을 멈추지 않는 한 계속 리스너가 동작하고 있고요.

위의 코드를 아래처럼 바꿔 지속적으로 받는 형태로 바꿨습니다.

function get_data_loop(today){
    api_call.on('ready', () => {
        function loop(){
            api_call.send({
                or_ordr_dt: today  // 오늘 날짜
            });
        };
        setInterval(()=>{
            loop();
        },1000);
    });
    api_call.on('getData', (data) => { 
        console.log(JSON.stringify(data)); 
    });
};
get_data_loop('20180830');

위처럼 바꾸니 1초에 한 번씩 지속적으로 받는 건 좋은데 지금 제가 필요할 때 한 번만 호출해야하는 상황이 생겼습니다.

위의 코드를 제가 원할 떄 한 번만 받는 방법이 없을까요?

참고로 맨 위의 코드를 setInterval로 호출하면 리스너 에러가 납니다.

원할 떄 한 번만 .send 호출을 하면 될 것 같은데 적절한 방법이 안 떠오르네요.

ps. 두번쨰 코드에 if(isOn == true){loop();} 와 같이 if를 사용하는 방법이 아닌 정말 .send를 한 번 보내는 방법이 있다면 좋겠네요.

  • 위의 코드에서 var api를 정의해 놓고 안 쓰고 있는데 이게 맞는 건가요? 엽토군 2018.8.30 15:27
  • 답변을 길게 적다가 생기는 의문이 있어서 다 지웠습니다. '필요할 때 한 번'이 어떤 의미인지 모르겠네요. 비동기인 소켓 이벤트 로직들과는 독립되어서 send()를 따로 호출하고 'getData' 이벤트 핸들러 안에서 받고 싶으신건가요? doodoji 2018.8.30 15:30
  • @엽토군 var api가 send로 보내는 것입니다. TaeSun Yoo 2018.8.31 08:52
  • @doodoji 필요할 때 한 번이라는 건 특정 이벤트 발생시 .send를 한 번만 보내 getData 이벤트 핸들러 안에서 받는 것을 의미하는 것입니다. 다음에는 보다 더 자세하게 적도록 하겠습니다. TaeSun Yoo 2018.8.31 08:53

1 답변

  • 좋아요

    2

    싫어요
    채택 취소하기

    일반적으로 접근해보자면 모든 웹소켓 통신 로직들은 'ready' 이후에 동작해야 합니다.

    작성하신 코드를 기준으로 작성해 보자면 그냥

    const today = ‘20180830’;
    
    api_call.on('ready', () => {
        setInterval(()=>{
            api_call.send({ or_ordr_dt: today });
        }, 1000);
    
        // 원하는 이벤트도 이 안에서 등록
        something.on(‘event_type’, (date) => {
            api_call.send({ or_ordr_dt: date })
        });
    });
    
    api_call.on('getData', (data) => { 
        console.log(JSON.stringify(data)); 
    });
    

    이런식으로 비동기인 소켓 핸드쉐이킹 이 후, 즉 'ready' 이벤트 핸들러부터 메인 로직이 나와야 될 것 같습니다.

    작성하진 구조를 그대로 가져가려고 하면 무엇이 먼저 와야 하는지 알기 힘들어져 코드를 작성하기 힘들어 집니다. 그렇다고 웹소켓이 준비 완료될 때까지 메인쓰레드가 마냥 기다릴 수는 없는 거고요.(blocking)

    동기화 로직이 꼭 필요하다면 async/await를 써 볼수도 있겠지만 그런 수고를 하는 것 보다는 위처럼 code flow 자체를 다르게 가져가는 것이 나아 보이네요.

    • 안에 만든 이벤트에미터를 바깥에서 동작시키려면 something.emit('event_type',date) 이런 식으로 호출하는 것이 맞나요? TaeSun Yoo 2018.8.31 18:56

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)