• 목록
  • 아래로
  • 위로
  • 2
  • Hanam09
  • 조회 수 220

안녕하세요. 좋은밤입니다.

웹 앱을 개발하던중 JS의 localStorage문제가 있어서 이렇게 글을 쓰게되네요.





한 차트를 일괄 다운로드시 다운로드 기록을 LocalStorage에 저장하여야 하는데 가장 마지막 음악만 저장됩니다ㅠㅠ.

또 다운로드도 Chrome과 Opera에서 일부 파일이 누락되는 현상도 발생하고요.

function downloadTrend() {
    if (!window.proxy.isProcessing) {
        var trends = window.proxy.getTrends.getSelectedRowIds();
        if (trends.length > 0) {
            mdc.exports.dialog("The download will begin.", "Download " + trends.length + " song.\nMusic that previously had a download history won't download.", {
                "download": function () {
                    mdc.exports.snackbar("Download started.");
                    window.proxy.isProcessing = true;
                    for (var i = 0; i < trends.length; i++) {
                        if (localStorage.getItem(trends[i]) == undefined) {
                            var xhr = new XMLHttpRequest();
                            var vId = trends[i];
                            xhr.open("GET", iTrendApiUri + "process.php?id=" + vId);
                            xhr.send();
                            xhr.onreadystatechange = function () {
                                if (this.status == 200 && this.readyState == 4) {
                                    var res = JSON.parse(this.response);
                                    if (res.success) {
                                        fetch(iTrendApiUri + "v/" + res.hash + ".mp3").then(response => response.blob()).then(blob => {
                                            const url = window.URL.createObjectURL(blob);
                                            const a = document.createElement("a");
                                            a.style.display = "none";
                                            a.href = url;
                                            a.download = res.audio + ".mp3";
                                            document.body.appendChild(a);
                                            a.click();
                                            window.URL.revokeObjectURL(url);
                                            document.body.removeChild(a);
                                            console.log(localStorage)
                                        }).catch(fail => {
                                            console.log("Missing download list:" + res.audio);
                                            mdc.exports.snackbar("Missing download list:" + res.audio)
                                        });
                                        window.localStorage.setItem(vId, new Date)
                                    } else {
                                        console.log(res);
                                        mdc.exports.snackbar("ERROR: " + res.audio + ": " + res.reason)
                                    }
                                } else if (this.readyState == 4) {
                                    mdc.exports.snackbar("ERROR: Unable to connect: iTrend DL Server")
                                }
                            }
                        }
                    }
                    window.proxy.isProcessing = false
                }
            })
        } else {
            mdc.exports.snackbar("Please select a song to download.")
        }
    } else mdc.exports.snackbar("Error: There is another work in progress")
}


일단 Success라면 저장이 되어야 되는데 무시되네요ㅜㅜ 왜인지 모르겠습니다.

구글에 찾아보니까 같은 현상을 겪는 사람들이 전무한가 봅니다.



그리고 이 서비스에서 차트를 불러오는데 다음과 같은 PHP 소스를 사용하는데요.

$url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&key={$key}&playlistId=".$playlist[$_GET["region"]];

$api = json_decode(file_get_contents($url),true);
$main = $api["items"];

$response = array();

$allVideoId = array();

for ($e=0; $e < count($main); $e++) { 
$videoElement = $main[$e]["snippet"]["resourceId"]["videoId"];
array_push($allVideoId, $videoElement);
};
/*
Trend Music Get PlayTime
*/
$__trendGetPlayTimeByVid = urlencode(implode(",", $allVideoId));

$url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails&key={$key}&id=".$__trendGetPlayTimeByVid;

$rawVideoDetails = json_decode(file_get_contents($url),true);
$videoDetails = $rawVideoDetails["items"];
/*
Trend Music Get Artist
*/
$url = "https://www.googleapis.com/youtube/v3/videos?part=snippet&key={$key}&id=".$__trendGetPlayTimeByVid;

$rawVideoSnippet = json_decode(file_get_contents($url),true);
$videoSnippet = $rawVideoSnippet["items"];


/*
Manufacture Contents
*/
for ($i=0; $i < count($main); $i++) {
$v = array();
$video = $main[$i]["snippet"];

$v["title"] = $video["title"];
$v["id"] = $video["resourceId"]["videoId"];
$v["description"] = $video["description"];
$v["playtime"] = $videoDetails[$i]["contentDetails"]["duration"];
$v["artist"] = str_replace(" - Topic", "", $videoSnippet[$i]["snippet"]["channelTitle"]);

array_push($response, $v);
}
$response = json_encode($response);
echo $response;


이게 엄청 작업 처리 속도가 엄청 느립니다. 그래서 자체 캐싱시스템을 사용하긴 하는데 초기 로딩시에는 속이 터질정도로 느립니다.


동기적으로 처리하는것 같아서 그러는것 같은데 PHP만으로 이 작업 속도를 끌어 올리는방법은 없을까요?

이거 하나 때문에 Node.js 로의 언어 변경도 생각중입니다.


JS PHP 고수분들 도와주세요!


작성자
Hanam09 36 Lv. (50%) 106610/109520EXP

 

안녕!

 

댓글 2

Seia
profile image

JavaScript와 서버와의 연계에서 많이 고민을 하고 계시는군요... ㅜㅜ
 
일단 코드에서 가독성이 보이지 않아 보는데에 시간이 조금 오래걸렸습니다.
함수형 프로그래밍에 대해서 조금 참고한다면 함수를 재사용성 높게 사용해서 지금보다 훨씬 깔끔하게 사용할 수 있을 듯합니다.  
 
일단 코드의 속도와 달리 몇가지 문제점을 찝을 수 있는데 fetch API에 대해서는 polyfill을 사용하시는 것을 추천드리며, GItHub에서 개발된 fetch polyfill이 있습니다. 아래 링크를 참고해주시면 됩니다. 그리고 모든 XHR로 Req되는 부분을 fetch api로 바꾸심이 어떤가 합니다.
> https://github.com/github/fetch
* IE에서는 async/await/promise 또한 polyfill 해주셔야 합니다.


 

순차적으로 하나하나씩 다운로드하는 편을 추천드립니다. 순간적으로 부하가 집중되는 것이 아닌지는 잘 모르겠습니다...


PHP는 깊게 파지 않아 많은 조언을 드릴 수는 없지만 구조적으로 개선하여 가독성을 올리신 뒤에 다시시도하시면 보이지 않을까 합니다.


그리고 다운로드 누락은 요청을 검사하여 오류가 발생했을 경우에 다시시도하시는 편이 좋을 듯합니다.

보통 다운로드할 수 없는 음악은 국가 제한 등에 의해 막히기 때문입니다.


그리고 Node.JS로 넘어오셔도 궁극적으로 해결해야 할 문제가 있습니다.



Google의 YouTube는 지속적으로 현재와 같은 허가되지 않은 크롤링을 차단하기 위해서 Ratelimit 정책을 시행 중에 있습니다.

> https://streamdroid.org/youtube-blocks-popular-mp3-stream-ripping-sites/


많은 Discord 뮤직 봇들과 YouTube 다운로드 사이트들은 제가 알기로는 매우 많은 클라우드 서버들을 통해서 IP 주소를 무작위로 사용하는 방법에 놓여 있으니 참고 바랍니다.



위와 같이 나올 수 있습니다. (작성자님의 사이트 로그)


보통 이런 다운로드나 미러 서비스는 수많은 양의 자체 미러 서버나 분산 처리를 위한 준비가 되어 있어야 안정적으로 운영할 수 있다고 생각됩니다.

comment menu
2019.10.31. 19:48

신고

"Seia님의 댓글"

이 댓글을 신고 하시겠습니까?

Hanam09 작성자 → Seia
profile image

안녕하세요. Seia님!

 

소중한 시간을 들여 저의 사이트에 대한 피드백을 주심에 대하여 정말로 감사드립니다.

Seia님의 짚어주신점을 잘 듣고 개선해보도록 하겠습니다.

 

"일단 코드에서 가독성이 보이지 않아 보는데에 시간이 조금 오래걸렸습니다.

함수형 프로그래밍에 대해서 조금 참고한다면 함수를 재사용성 높게 사용해서 지금보다 훨씬 깔끔하게 사용할 수 있을 듯합니다. "

 

함수형 프로그래밍에 대하여 배우고 코드를 개선해보도록 하겠습니다.

 

"Google의 YouTube는 지속적으로 현재와 같은 허가되지 않은 크롤링을 차단하기 위해서 Ratelimit 정책을 시행 중에 있습니다."

 

자체적으로 이 정책을 우회하는 시스템이 구축되어 있어서 별 문제는 되지 않았습니다.

신경써주셔서 감사합니다.

 

그리고 PHP 서버코드는 구조를 개선하고 속도를 높일 수 있는 방법을 찾았습니다.

 

"순차적으로 하나하나씩 다운로드하는 편을 추천드립니다. 순간적으로 부하가 집중되는 것이 아닌지는 잘 모르겠습니다..."

 

순차적으로 하나하나씩 다운로드하는것이 localStorage 문제가 발생하지 않을까요? 서버 부하량은 방지대책이 있어서..

조언을 듣고 시도해보겠습니다.

정말로 답변해주셔서 감사합니다.

좋은하루되세요!

comment menu
2019.11.01. 00:11

신고

"Hanam09님의 댓글"

이 댓글을 신고 하시겠습니까?

권한이 없습니다.
번호 제목 글쓴이 날짜 조회 수
공지 [작업 완료] 설 명절 맞이 서버 업데이트 안내 3 마스터 24.02.11.17:21 1008
공지 [중요] 호스팅 만료와 관련하여 일부 수칙이 변경됩니다. 4 마스터 23.01.14.02:23 4684
공지 [필독] 질문하는 방법 17 마스터 18.02.23.03:09 4480
246 그누보드에서 과도한 POST 요청을 보내는 매크로를 이용한 DDoS에 대해 질문 드립니다. 6 image 이니스프리 20.02.20.13:17 676
245 고정된 요일에 카운트다운되는 소스가있나요? 4 슬기 20.02.20.19:45 202
244 사이트 접속 불가 5 image 입체그림 20.02.21.09:39 236
243 에러 523 해결법 4 입체그림 20.02.21.16:48 6726
242 클라우드 플레어를 특정 PHP 파일에 연계되도록 설정할 수도 있는가요?? 이니스프리 20.02.21.21:18 188
241 홈서버용 CPU 좀 봐주시면 감사하겠습니다~ ㅠㅠ 7 image 이니스프리 20.02.24.22:40 218
240 [파이썬] Temporary failure in name resolution에 대해 여쭤봅니다 2 이니스프리 20.02.25.11:50 987
239 [파이썬] 웹 페이지 크롤링 시 조건에 따라 보여졌다 안보여지는 class를 조건문으로 사용 하고 싶은데요.. 4 위돈톡애니모 20.02.25.15:19 1333
238 [해결][CURL/PHP] 스터디포어스서버에서의 PHP CURL에 대한 특정 서버의 잘못된 응답에 대하여 3 Hanam09 20.02.27.15:36 310
237 스터디포어스 웹호스팅상에서 비주얼에디터 설치하는 중 오류가 났습니다 ㅠㅠ image 입체그림 20.02.28.14:40 207
236 VPS 플랜 선택과 관련하여 질문 드립니다 ^-^ 4 image 이니스프리 20.02.28.20:52 215
235 XE 에디터가 작동하지 않아요 ㅠㅠ 4 image 입체그림 20.03.03.17:30 219
234 [파이썬] 윈도우에서 datetime 객체의 invalid format string 에러 3 이니스프리 20.03.04.15:52 1488
233 그누보드5 홈피 관리해주실분 찾습니다. 찰리 20.03.04.23:10 206
232 브라우저 개발자도구에서 formdata를 숨기는 방법이 있는가요? 6 이니스프리 20.03.07.23:54 2635
231 페북이나 트위터처럼 태그 속성이 자주 변경되는 사이트의 크롤링은 어떻게 해야 될까요?? 4 이니스프리 20.03.09.00:27 240
230 VPS 웹서버 설치 후 보안을 위해 추가로 해야되는 조치에는 어떤 것이 있을까요?? 6 이니스프리 20.03.13.22:46 249
229 그누보드용 회원차단 크롬 확장프로그램을 만들어보려는데요~ ^-^ 7 이니스프리 20.03.24.23:53 263
228 안녕하세요ㅠㅠ 위키 URL 리다이렉션 관련 질문입니다 1 김광현 20.03.26.16:33 228
227 크롤링 용도로 사용하는 VPS의 트래픽이 얼마나 될까요?? 2 이니스프리 20.03.29.21:02 262