제가 4월 초 부터 날씨 위젯의 air 값이 제대로 반영이 안되는 문제를 이야기 하고 있는데요. 

 

이상하게 되는 많은 부분이 조금씩 밝혀지는 듯 합니다.

 

그 중 하나가 api 에서 정상적인 값이 반환되지 않는 경우가 너무 자주 있습니다. 

 

이때 응답값 중에 status 가 ok 를 가지지 못합니다. 그래서 ok가 아닌 경우는 아예 이후 진행을 멈추게 하려고 코드를 삽입 하려고 합니다.

 

 

//공기
        $aqicn_url = 'https://api.waqi.info/feed/geo:'.$geo->lat.';'.$geo->lng.'/?token='.$_aqicn_token;
        if($air = json_decode(self::file_get_contents_curl($aqicn_url, $_timeout)))
        {
            if($air->status!='ok')
            {
                return false;
            }

            $new_data->aqi = self::getAirQualityIndex((int)$air->data->aqi);
            $new_data->aqi->pm10 = $air->data->iaqi->pm10->v;
            $new_data->aqi->pm10_color = self::getAirQualityIndex((int)$new_data->aqi->pm10, 'color');
            $new_data->aqi->pm25 = $air->data->iaqi->pm25->v;
            $new_data->aqi->pm25_color = self::getAirQualityIndex((int)$new_data->aqi->pm25, 'color');
            $new_data->aqi->time = date('H:i', strtotime($air->data->time->s));
            $new_data->aqi->time_full = $air->data->time->s;
        }
        elseif($cache_data)
        {
            $new_data->aqi = $cache_data->aqi;
        }

        //날씨

 

 

 

붉은색으로 표시한 부분이 제가 추가한 부분인데요. 이렇게 처리하면 될까요??

 

저렇게 넣고 테스트를 처음 하는데 마침 status 값이 ok 가 아닌 것이 반환되었는지 값이 저장되지 않더라구요.

그이후 다시 페이지를 새로고침하니까 그때 status가 ok 였는지 진행이 되어 새로운 값으로 반영이 되었습니다.

 

 

응답하는 값들은 이렇습니다.

 

{"status":"ok","data":{"aqi":102,"idx":1437,"attributions":[{"url":"http://www.semc.gov.cn/","name":"Shanghai Environment Monitoring Center(上海市环境监测中心)"},{"url":"http://113.108.142.147:20035/emcpublish/","name":"China National Urban air quality real-time publishing platform (全国城市空气质量实时发布平台)"},{"url":"https://china.usembassy-china.org.cn/embassy-consulates/shanghai/air-quality-monitor-stateair/","name":"U.S. Consulate Shanghai Air Quality Monitor"}],"city":{"geo":[31.2047372,121.4489017],"name":"Shanghai","url":"http://aqicn.org/city/shanghai/"},"dominentpol":"pm25","iaqi":{"co":{"v":4.6},"d":{"v":6},"h":{"v":31},"no2":{"v":17.9},"o3":{"v":69.5},"p":{"v":1018},"pm10":{"v":41},"pm25":{"v":102},"so2":{"v":5.1},"t":{"v":24},"w":{"v":4.9},"wd":{"v":290}},"time":{"s":"2018-05-03 13:00:00","tz":"+08:00","v":1525352400}}}

 

  • profile

    거기서 return하시면 아래에 있는 날씨 부분이 전혀 처리되지 않습니다.

    어제처럼 몇 시간씩 대기정보 api가 다운되면 날씨도 하나도 안 나오는 문제가 생길 수 있습니다.

    대기정보는 안 나와도 날씨는 나와야지요....

     

    1. 정상적인 정보를 받아온 경우: 새 정보를 표시하고 캐시에 저장함

    2. 정상적인 정보를 받아오지 못한 경우:

      2-1. 캐시된 정보가 있는 경우: 캐시된 정보를 표시함 (캐시에 다시 저장하지는 않음)

      2-2. 캐시된 정보가 없는 경우: "미수신"이라고 표시함 (캐시에 다시 저장하지는 않음)

     

    이렇게 3가지 가능성으로 나눠서 if/else 처리하고, 맨 밑에 캐시 저장하는 부분에도 조건을 걸어야 할 것 같네요.

  • profile profile

    일단 급하게 제가 먼저 저희 사이트 처리하려고 전체를 중지하는 것으로 적용해 봤습니다.

    갱신 자체가 중단되는 것이죠.
    방문자가 저 날씨정보를 갱신하려 메인페이지에 접속하는 건 아니니까 페이지 를 왔다갔다 하다 우연히 리턴에 걸리면 중지 되었다가 다시 새롭게 페이지가 로딩되면 정상값이 출력되도록 하는 것도 큰 개선일 것 같아서요.
    비정상 값이 캐시되는 것을 막고자 하는 것이 가장 지금 시급한 상황이었습니다.

     

    *의외로 꽤 많은 빈도로 status 가 nug  값을 가진 비정상 반환이 발생합니다.


    보다 더 좋은 방법은 자료 제작자분께서 처리해 주시면 좋을 것 같아요.

  • profile profile
    일단 제대로 된 코드가 나오기 전까지 air api가 다운되는 일이 발생하지 않기를 기대합니다 ㅋ
  • profile

    아, 그리고 객체를 반환해야 하는 함수가 뜬금없이 false를 반환하면 그걸 받아서 가공하는 쪽에서 오류가 날 수도 있습니다. $new_data에 아직 아무 것도 채워지지 않은 상태이니, return $new_data; 하면 원래의 의도에 더 잘 맞을 것 같아요.

  • profile profile
    네. 알못이라 설명해주셔도 잘 모르니 일단 말씀 하신대로 고쳐 놓겠습니다.
    이렇게라도 해 놓으니 이제 잘못된 정보로 표시되는 일은 없어졌네요.
  • profile

    차라리 air staus가 ok 가 아닌 응답이 올때

    그냥 그걸 "미수신" 으로 출력되게 두고

    마지막에 캐시 저장만 되지 않게 하는게 더 좋은 방법일 수도 있을 것 같습니다.
    air 값은 비정상값 출력
    날씨 불러오는 코드 정상 진행
    캐시 저장하는 조건에 status ok 조건을 추가..


    위쪽에 조건을 따로 걸지 않고 그대로 두고..

    if($oCacheHandler->isSupport() && $air->status=='ok')
    {
    if($oCacheHandler->isValid($cache_key))
    {
    $oCacheHandler->delete($cache_key);
    }

    $new_data->mk_time = time();
    $oCacheHandler->put($cache_key, $new_data, 86400);
    }


    이렇게 하면 어떨까 해서 고쳐 보았네요.