기본 콘텐츠로 건너뛰기

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를 쓰니까 앓던 이가 빠진 느낌. 이 조합은 당분간 계속 써야겠다 싶다.

LG G Pro 2 Custom Rom +Rooting 기록

선 루팅 https://forum.xda-developers.com/lg-g3/general/guide-root-lg-firmwares-kitkat-lollipop-t3056951 1.2버전 스크립트 모드로. echo Looking for LG serial port.. echo. adb.exe wait-for-device 여기에서 정체 상태여서 강제로 adb kill-server 했더니 알아서 재부팅하심. 폰에선 "펌웨어 업데이트"화면이 나오고 Phone found at COM5! Rooting phone.. If you don't see the SuperSu installer script runs within about a minute, then the root failed. Author : blog.lvu.kr SPECIAL COMMAND : ENTER, LEAVE ## 이런 상황이 됨. #이 느린 속도로 하나씩 증가하고 있음. 한 시간 기다려도 성과없음. 뭐 몇번해봐도 안되고 결국 불안하긴 하지만 kingroot.net  로 설치 롤리팝이니까  https://drive.google.com/file/d/0B4kfGU1z_PClQ3AyM2lKOGR1S3M/view  이걸 받아서 압축 풀기. d838recovery.bat 만 있어서 당황스럽긴한데 실행하고 1번 하니까 리커버리 모드 진입까진 잘 되는 듯. adb sideload 라는게 있어서 해봄. Advance에서 adb sideload 선택하고 USB연결한 PC에서 adb sideload RR-N-v5.8.5-20171010-d838-Final.zip 하니까 착착 잘 진행됨. 이제 흉측한 U+LTE 가 없어짐. ㅇㅋ 군더더기 없고 깔끔한데 남은 건 gapps 를 설치해야함. http://opengapps.org/  를 권해줘서 갔는데 지옥 느림. ARM + 7.1 + stock 이 기본이...