기본 콘텐츠로 건너뛰기

Meteor에서 file API를 사용한 upload 방법

https://gist.github.com/4132544
코드는 이쪽에.

Meteor.saveFile = (file)->
  fileReader = new FileReader()
  fileReader.onload = (blob) ->
    Meteor.call 'saveFile',
      file:file
      blob:blob.srcElement.result
  fileReader.readAsBinaryString file
  return
# event for upload
_.extend Tempalte.something,
  events:
    'change input[name=attach]': (e)->
      _.each e.srcElement.files, (file) ->
        Meteor.saveFile file

클라이언트에서 FileReader 객체를 생성하고 onload 시 파일속성과 바이너리를 인자로 Call을 해준다. submit을 타지 않고 Call을 사용하여 직접 전송한다는 점에 주목.

app=__meteor_bootstrap__.app
  fs=__meteor_bootstrap__.require 'fs'
  app.stack.unshift
    route: '',
    handle: (req, res, next)->
      Fiber(->
        unless /upload\/\/*/gi.test req.url
          next()
        else
          res.write fs.readFileSync("#{process.cwd()}/server/tests/upload/images/#{req.url.replace('/upload/','')}")
          res.end()
      ).run()
  Meteor.methods
    saveFile: (param)->
      if param.file.type.indexOf('image')+1
        Fiber(->
          fs.writeFileSync "#{process.cwd()}/server/tests/upload/images/#{param.file.name}",param.blob,'binary'
        ).run()

Meteor.methods부분 : 서버쪽에서 saveFile이란 method를 받으면서
file이름과 바이너리를 받아 파일 쓰기를 한다.
이때 경로는 tests 경로 아래로 두는데 프로젝트 디렉토리가 아닌 곳으로 해줘도 상관없지만
프로젝트 디렉토리 아래 업로드할 파일을 적재할 경우
Meteor가 파일 생성 여부를 스캔하여 어플리케이션을 재시작하는 것을 방지하기 위해
예외 디렉토리인 tests 를 사용한다.

이렇게 저장한 업로드 파일은 /public 디렉토리 아래에 있지 않아 직접 링크를 전달할 수 없다.

Routing 부분 : __meteor_bootstrap__.app 객체로부터 stack에 request 처리를 직접해준다.
route 를 '' 로 할 경우 모든 요청에 대한 처리를 할 수 있으므로 이를 사용한다.
그러면 handle에서 request별 처리를 할 수 있는데
우리는 /upload/xxxxx 형태의 요청에 대해서만 처리하고 나머지는 next()를 사용해 포워딩해주기로 한다.
해당 형식의 URL 요청을 받을 경우 methods 에서 저장한 디렉토리 경로를 붙여서 response 에 write 해준다.

서버 사이드에서 파일을 읽거나 쓸때 병목을 방지하기 위해서 깨알 Fiber를 붙여줌.
readFileSync 나 writeFileSync 대신 readFile / writeFile 을 써서 callback으로 처리해도 되지만 예외처리 등등 귀찮기도 하고 meteor 디자인 가이드에서 CPS 스타일을 참아달라는 부탁이 있어서 Fiber + Sync 로 구현.

이런 건 뭐 메뉴얼에도 없고 검색도 안되니 소스를 뒤져보는 수밖에.
누군가 보고 '이렇게 하는게 더 나아요'라고 제시해줬으면 싶지만 현재로는 이게 제일 맘에 든다.

댓글

이 블로그의 인기 게시물

세상 간단한 https(+secured websocket): Caddy

nginx, apache2 같은 걸로 매번 certbot 연동을 통해 https 하는게 지겨워서 알아보니 Caddy라는게 있더라. 설치법은 강하게 크기 위해 알아서 해본다. # cat /etc/caddy/Caddyfile your.shitty.site:8123 {   proxy / localhost:9123 {     websocket     transparent   } } 이건 외부에서 8123으로 들어오는 걸 내부적으로 9123로 맞춰서 https 맞춰주는 reverse proxy. 만일 port를 생략하면 # cat /etc/caddy/Caddyfile your.shitty.site {   proxy / localhost:9123 {     websocket     transparent   } } 기본포트인 443으로 되어 https://your.shitty.site 로 접속이 된다. 요새 말썽이던 cloudflare 버리고 netlify domain이랑 caddy를 쓰니까 앓던 이가 빠진 느낌. 이 조합은 당분간 계속 써야겠다 싶다.

저지연 오디오 생성 LLVC 사용기

https://github.com/KoeAI/LLVC 써봄 CUDA 11.8 버전 쓰고 있어 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 VC 없어서 설치 https://wikidocs.net/168848 참조 FAIRSEQ 관련 오류 https://github.com/facebookresearch/fairseq/issues/2908 pip install editdistance  설치 No CUDA runtime is found, using CUDA_HOME='C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8' 오류 멀쩡하게 있는데 안됨. pip install torch==2.1.0+cu118 torchvision==0.16.0+cu118 torchaudio==2.1.0+cu118 --extra-index-url https://download.pytorch.org/whl/cu118 다시 설치 set DISTUTILS_USE_SDK=1 이게 문젠가 설정하고 재도전 Using cached ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl (118 kB) Building wheels for collected packages: fairseq   Building wheel for fairseq (pyproject.toml) ... error   error: subprocess-exited-with-error   × Building wheel for fairseq (pyproject.toml) did not run successfully.   │ exit code: 1   ╰─> [1829 lines of output]       No CUDA runtime is found, usi...