<aside> 고화질 음원 파일, 뮤직비디오 등과 같은 대용량 파일 업로드는 단순히 multipart/form-data로 파일 업로드를 하게 되면 파일 크기 제한 등의 문제가 발생할 수 있습니다. 또 대용량의 파일을 업로드하는 도중에 사용자가 다른 작업을 할 수 없는 비효율도 발생합니다. 이때 소켓 통신을 통해 파일 업로드를 진행시켜놓고 지속적인 콜백으로 처리율도 받아보면서 사용자는 다른 작업도 진행할 수 있습니다.

</aside>

대용량 파일을 업로드 하면서 청크 단위로 서버에 저장하는 상황입니다.
해당 이미지는 GIF 이미지로 PDF시 정적인 이미지로 대체되며, 자세한 내용은 노션에서 확인 할수 있습니다.

대용량 파일을 업로드 하면서 청크 단위로 서버에 저장하는 상황입니다. 해당 이미지는 GIF 이미지로 PDF시 정적인 이미지로 대체되며, 자세한 내용은 노션에서 확인 할수 있습니다.

클라이언트 부분

image.png

사용자가 파일을 드래그 앤 드롭했을 때 이벤트를 감지합니다. 그리고 여러 개의 파일일 경우와 하나의 파일일 경우에 대한 for 문 처리를 진행합니다.

image.png

그리고 upload-start를 통해서 업로드를 시작하는데 만약 이 과정에서 인증이 된 사용자만 업로드가 되고 싶다고 한다면 전달되는 파라미터로 인증에 필요한 토큰 값을 전달합니다.

image.png

가장 핵심 부분인 파일을 조각조각 나눠서 서버로 업로드하는 기능입니다.

readChunk()가 한번 호출이 되고 chuck 크기만큼의 잘라내어 readAsArrayBuffer() 메서드를 통해 파일을 읽고 나면, onload 이벤트 발생으로 서버에게 데이터를 전달합니다. 이때 FileReader가 읽은 파일 데이터는 ArrayBuffer 형식으로 제공되는데 ArrayBuffer를 Unit8Array(8비트 부호 없는 정수)로 변환합니다.

대부분의 파일 형식을 바이트를 기반으로 구성되어 있고, 작은 크기의 데이터 요소를 표현하는데 최적화되어 있는 1바이트로 변환하였습니다.

소켓 호출이 완료되고 시작점을 변경한 뒤 다시 readChuck()를 호출하여 재귀적으로 서버에게 파일 데이터를 전달합니다.

서버 부분

image.png

커넥션이 이뤄지고 mkdirSync를 통해 디렉터리를 생성합니다. 만약 temp까지 생성되어 있지 않다면 {recursive: true} 옵션으로 중간 디렉터리까지 생성하게 만듭니다.