기본 콘텐츠로 건너뛰기

8월, 2012의 게시물 표시

Meteor 에서 REST 사용

Meteor 에서 file-upload 라던가 REST API 같은 걸 제공하려면 request 를 받아서 처리할 수 있어야하는데 Meteor 에선 지원하지 않아 좀 답답한 면이 있다. 하지만 그래봤자. Node.js 고 connect 프레임워크를 사용하고 있기 때문에 저번에 언급한 적이 있던 __meteor_bootstrap__ 를 이용해보자. ./.meteor/local/build/server/server.js 를 보면 서버쪽 구동부를 볼 수 있는데 run function 쪽을 보면   __meteor_bootstrap__ = {require: require, startup_hooks: [], app: app}; 이런 코드가 있다. 여기서 app은? 그 위쪽에    var app = connect.createServer(); 어이쿠 connect 네. 게임 끝나셨다. 서버쪽에 아래와 같이 stack array 에 route 를 추가하면 된다. Meteor.startup ->   app=__meteor_bootstrap__.app   app.stack.unshift     route: "/api",     handle: (req,res)->       res.statusCode = 200       res.write "OK"       res.end() 다행이야 다행이군!

meteor 0.3.9 에서 사용자 인증을 써보자.

예전에 everyAuth 에 대한 글을 쓴적이 있는데 https://github.com/meteor/meteor/wiki/Getting-Started-with-Auth meteor wiki에 위와 같은 글이 있더라. 발빠르다 meteor. 투자받더니 탄력이 붙었는지 쭉쭉 잘나가는군. 일단 meteor 설치부터 다시하자. 이전에 Quick start 가이드대로 curl https://install.meteor.com | /bin/sh 이렇게 설치했지만. 이번엔 git 에서 auth Branch를 따서 갈 것이므로 수동 설치하자. git clone git://github.com/meteor/meteor.git cd meteor 수동설치래봤자 적절한 곳에 clone 하고 인스톨 하는게 전부인데. auth는 다른 branch에 있기 때문에 일단 clone 하고 해당 경로에 진입만한 상태에서 git branch -r 로 리모트 브랜치를 확인해보자   origin/HEAD -> origin/master   origin/auth   origin/auth-email   origin/auth-test-isolation   origin/auth-twitter   origin/avital   origin/avital-remove   origin/avital-watch   origin/david-handlebars   origin/dev-bundle-bump   origin/devel   origin/email   origin/forms   origin/jade   origin/master   origin/release-0.1   origin/release-0.1-templates   origin/spark   origin/spiderable   origin/test-isolation   origin/version-bump   origin/webgl   origin/wrappedjs   origin/{

angular.js + node.js + express 로 JSONP 구현을 해보았다.

크로스도메인 문제(다른 사이트의 ajax를 호출할 수 없는 브라우저의 보안정책)를 피하기 위해 JSONP라는 대안이 있는데 angular를 이용해 간단하게 목록을 가져오는 외부 호출을 만들어보자. http://docs.angularjs.org/api/ng.$http#jsonp 내용을 보고 참조하였다. index.html <!DOCTYPE html> <html ng-app > <head>     <title></title>     <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>     <script type="text/javascript" src="todo.js"></script> </head> <body> <div>     <div ng-controller="listController" >         <ul>             <li ng-repeat="list in lists" >                 {{list.author}}             </li>         </ul>     </div> </div> </body> </html> ng-app 을 설정하고 listController 에 lists 객체로부터 author 목록을 가져오게 하자. todo.js listController = function($scope,$http) {     angular.extend($scope,{         query:function() {          

javascript에서 forEach의 성능 문제

http://jsperf.com/for-vs-foreach/9  를 보고 forEach가 정말 그렇게 느려? 라고 생각이 들어서 node 커맨드라인을 열고 아래와 같이 처 넣고 실행. 어짜피 IE에서도 안되는거 Array를 prototype 확장하여 forEach 를 만들어서 쓰곤 했다. Array.prototype.forEach=function(callback) {   for (var i=0,len=this.length; i<len; i++) {     callback(this[i], i);   } } 그래서 이것도 넣어서 같이 돌려봤다. -------------------------- var i, values = [], sum = 0; for (i = 0; i < 10000; i++) {  values[i] = i; } function add(val) {   sum += val; } var itercount =2000; sum=0; time = +new Date(); for (var _i=itercount; _i>=0; _i--) {   values.forEach(add); } console.log("forEach legacy:"+ (+new Date()-time)); sum=0; time = +new Date(); for (var _i=itercount; _i>=0; _i--) {   for (i = 0; i < values.length; i++) {     add(values[i]);   } } console.log("simple for:"+ (+new Date()-time)); Array.prototype.forEach2=function(callback) {   for (var i=0,len=this.length; i<len; i++) {     callback(this[i], i);   } } sum

XCode OS X Application : Drag & Drop 후 파일 처리

개인적으로 필요한 유틸이 있어서 appleScript 로 만들까하다가 XCode 4.4 로 OS X Application 을 만들어 본 적이 없어서 Drag & Drop, Pipe, File 처리 같은 걸 해봤다. xib 에 드래그할 대상인 NSImageView 를 놓고 그 NSImageView 를 Customize 한 NSCImageView 를 만들어서 구현했다. performDragOperation 이벤트에서  NSPasteboard  *paste = [sender draggingPasteboard]; 로 NSPasteboard 객체에 드래그 한 것들을 가지고 NSFilenamesPboardType 인것들을 타입으로 추출하여 NSData로 받았다. NSArray *fileArray = [paste propertyListForType : @"NSFilenamesPboardType" ]; 파일 목록은 propertyListForType으로 string array 를 받을 수 있다. http://borkware.com/quickies/one?topic=nstask shell 실행하고 결과 stdout 을 받는 것 처리하는데 위의 링크를 참조했다.   NSTask *task = [[ NSTask   alloc ]  init ];   [task  setLaunchPath : @" <SHELL COMMAND> " ]; NSTask 를 setLaunchPath 메서드를 사용하여 콜할 커맨드를 지정하고   [task  setArguments :[ NSArray   arrayWithObjects : <@args> , file,  nil ]]; N개의 argument 를 지정   NSPipe  *pipe=[ NSPipe   pipe ];   [task  setStandardOutput

express 2.0 에서 3.0으로 바꿀때 주의할 점.

하드 파티션이 날아가서 새로 셋업하고 작업하던 소스를 받아와서 아무생각 없이 npm install 했더니 express 3.0으로 되어있더라. 기존의 소스는 express = require 'express' gzippo = require 'gzippo' fs = require 'fs' http = require 'http' app = express.createServer() path = require 'path' tmpl =   compile: (source, options)->     (locals)->       # 여기에 템플릿 뽁찡       source   port = process.env.VMC_APP_PORT || 3000 app.configure ->   app.set 'views', "#{__dirname}/../public"   app.use app.router   app.set 'view options', layout: false   app.set 'view engine', 'html'   app.register '.html', tmpl   app.use gzippo.staticGzip "#{__dirname}/../public" app.get '/', (req,res) ->   res.render "./html/index.html" app.listen port, ->   console.log "Listening on #{port}" 이런 식으로 썼다면 express = require 'express' fs = require 'fs' http = require 'http' a

facebook, Google+, Diaspora* 3종 SNS AJAX 메시지 비교

일 관계로 SNS 비슷한 걸 만들고 있는데 데이터 모델을 하기 귀찮은 관계로 남이 한걸 베낄려고 facebook, google+, diaspora 의 XHR을 분석해보고 있다. 1. facebook 역시 예상했던 대로 지저분. entries 라는 객체 밑에 app, group, page, friendlist 등이 마구 혼재 본문 내용은 초기로드시에  <code class="hidden_elem" id="u33ari_19"><!-- <li>.... --> 이런 형태로 뿌리고 MoreStoriesPagelet 을 통해 Document 요청. app, group, page, friendlist 같은 건 본문과는 다르게 처리했는데 뭐 닭짓 아닌가? 하긴 원래 글 한번 쓰면 못바꾸는 구조로 처음에 만들어서 별도로 처리한득. 주기적으로 pull 이라는 heartbeat(클라이언트에서 서버찌르기)을 통해 json을 받아옴. for (;;); {"t":"heartbeat"} {"t":"heartbeat"} {"t":"continue","seq":2} 결과값은 이런 형태. 전세계 클라이언트로부터 DDOS 공격을 잘도 버티고 있네 ㅎㅎ 2. Google+ 얘들은 성능을 위해 json 데이터 구조를 사용하지 않는다. 그럼 어떻게 하냐고? )]}' [[["f.ri","12015082395849449"] ,["ghr",[] ] ,["di",136,,,,,[] ,[] ,,,[] ,[] ,[] ] ,["e",4,,,125] ]] 이런식의 중첩 배열을 사용한다. 마치 C Struct로 만든 전문통신을 보는 느낌

node.js(+express) everyAuth 적용기

node.js 용 package 중 everyAuth 라고 상당히 많은 서비스 API를 지원하는 훌륭한 라이브러리가 있다. facebook, google, twitter 는 물론이고 github 에서 instagram 까지도 지원한다. 맨땅에 하기엔 사실 사용자 로그인/인증이라는 과정이 간단하지 않다. 설명을 쭉 읽어보니 그냥 커스텀 인증을 한다고 해도 구조가 잘 잡혀있어서 써야겠다고 결심. express 프로젝트를 만들었다. 일단 facebook 부터 시작해보기로 했다. 먼저 OAuth 인증을 하려면 facebook 으로부터 appId 와 appSecret 두개 한쌍을 페어로 받아와야한다. https://developers.facebook.com/apps  에서 "새 앱 만들기"를 한다음 App Name을 정해주자. Namespace랑 Web Hosting은 사용하지 않으므로 그대로 내버려둠. 그러고 난 뒤 보안 텍스트 확인하면 앱 > 앱이름 > Basic 으로 이동한다. 보면 앱이름과 App ID, App Secret, 아이콘을 확인할 수 있다. 아이콘은 적당히 수정하면 되고 "기본정보"와 "어떻게 앱을 Facebook과 통합시킬지 선택하세요" 두가지 설정 항목이 있음을 확인하고 "어떻게 앱을 Facebook과 통합시킬지 선택하세요" 에서 Website with Facebook Login 를 체크하면 사이트 URL 을 넣을 수 있다. 리디렉트 할 사이트 URL 을 넣고 변경 내용 저장. 일단 이걸로 facebook 준비는 끝났다. 별도의 facebook 앱 페이지를 만들거나 할 필요는 없다. server.js 에 대략 구현하기를 (coffeescript) everyauth = require 'everyauth' # mock User list user = {} # set up for everyAuth