블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 3. 9. 17:47 Languages

Underscore.js 프레임워크를 보면 소스에 대해 왼쪽에는 주석을 오른쪽은 소스를 보여주며 설명을 한다. 이러한 문서를 자동으로 만들어 주는 툴이 Groc 이다. 또한 루트에서 수행을 하면 하위의 모든 소스에 대한 문서화를 자동으로 만들어 주고, GitHub과 통합할 수 있다 


1. Groc 설치하기 

  - 주석을 Markdown 형태로 작성한다

  - 마크다운 포멧은 배우기 쉽고 GitHub에서도 사용하므로 반드시 익혀두자 

  - GitHub의 페이지 publishing 과 통합된다 : GitHub에서 OSS(Open Source Software) 개발한 것을 공짜로 웹 서비싱 해준다

  - 검색 테이블을 제공한다 



2. 설치하기 

  - npm (Node Package Manager)가 설치되어 있어야 한다 

sudo npm install groc -g

npm http GET https://registry.npmjs.org/groc

npm http 304 https://registry.npmjs.org/groc

... 중략 ...

groc@0.3.2 /usr/local/lib/node_modules/groc

├── colors@0.6.0-1

├── spate@0.1.0

├── underscore@1.4.4

├── coffee-script@1.6.1

├── autorequire@0.3.4

├── showdown@0.3.1

├── optimist@0.3.5 (wordwrap@0.0.2)

├── jade@0.28.2 (commander@0.6.1, mkdirp@0.3.5)

├── uglify-js@2.2.5 (source-map@0.1.9)

├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.0, minimatch@0.2.11)

└── fs-tools@0.2.9 (async@0.2.6, lodash@1.0.1)


// syntax highlighting module pygments 설치하기

$ sudo easy_install Pygments

Best match: Pygments 1.6

Downloading http://pypi.python.org/packages/2.7/P/Pygments/Pygments-1.6-py2.7.egg#md5=1e1e52b1e434502682aab08938163034

... 중략 ...

Installing pygmentize script to /usr/local/bin   <== groc가 사용함



3. 문서만들기 

  - * 사용할 수 있다

  - 여러 옵션을 적용할 수 있다

  - CLI 명령으로 수행한다 : groc [js명칭]

  - github에서 groc를 다운받아서 직접 만들어 보자 

//////////////////////////////

// groc 소스 받아 문서 생성하기 

$ git clone https://github.com/nevir/groc.git

Cloning into 'groc'...

remote: Counting objects: 1215, done.

...중 략 ...


groc index.js

publish_to_github null https://github.com/nevir/groc origin

  Generating documentation...

✓ /Users/git-repositories/groc/.git/groc-tmp/languages.html

✓ /Users/git-repositories/groc/.git/groc-tmp/project.html

..중략..

✓ /Users/git-repositories/groc/.git/groc-tmp/styles/default/docPage.html

✓ Documentation generated


//////////////////////////////

// 디렉토리별로 .js 또는 .coffee 파일을 .html 파일로 문서화 한다

// git clone 후 

$ cd groc 디렉토리 이동후 모습 

// groc 를 수행한 후의 디렉토리 : lib 디렉토리에 있는 폴더를 상위 폴더로 올린다



///////////////////////////

// static 웹서버 구동 (참조)

$ static

serving "." at http://127.0.0.1:8080

17:35:09 [200]: /

17:35:09 [200]: /assets/style.css

17:35:09 [200]: /assets/behavior.js

17:35:09 [404]: /favicon.ico


  - 문서보기 : http://localhost:8080  Groc의 홈페이지 문서가 로컬에 만들어 졌다!


4. 사용 아이디어

  - GitHub에서 소스를 개발한다면 GitHub Page와 통합하여 API를 웹서비스 형태로 배포한다

  - 개발 소스에 대한 Code Review시에 Groc 문서로 만들어서 소스를 리뷰한다 

  


<참조>

  - Outsider dev 의 groc 소개

  - Pygments 설치하기

'Languages' 카테고리의 다른 글

APM 설치하기  (0) 2012.11.27
posted by 윤영식
2013. 2. 16. 11:21 NodeJS/Concept

웹 기술에 대한 발전방향을 고찰해 보자.


1) Physical Level

  - file base - static web (web server : content management, http 통신) - web browser (mime type)

    + Content Delivery Service

  - GET, POST 만 주로 사용



2) Logical Level

  - framework operation (MVC라는 server side기술에서 출발함)

  - controller : request/response, model : data, view : ui  

  - DRY Service: Don't Repeat Yourself 를 위한 좋은 framework으로 요즘 spring 을 기업에서 많이 사용함 

  - Routing 통한 RESTful Web Services : Data Service -> Cloud Service 로 발전 (CRUD 서비스를 GET/POST/PUT/DELETE)

  - RIA 기술의 태동 : 

  - MVC 초기 document base 에서 stream base 로 이동한다. 이에 따라 DB도 code first 로 이동하면서 어플리케이션과 merge를 쉽게 하는 방향으로 이동한다 

  - Data Service로 가면서 View가 없어지면서(None UI) SPA(MS의 서버사이드 기술임)을 스티브 샌더슨이 말하고 있다

  - 즉,  RIA (activex, flash, etc) -> SPA 로 변해감 (기술이 JavaScript로 통일되어 감)

  - application level 이다 



3) SNS Level

  - SNS 기술 : community level, Service Level 이다 

  - 2)의 application level 과 service level 로 구분된다 

  - Client-WebApp, Server-Node.js, NoSQL-MongoDB 기술들의 등장 

  - Client Side에서 SPA (Single Page Application)등장 : Backbone(Underscore), Angular (DI 존재), Ember (DI 없음)

   + 2)레벨의 MVC는 의미가 희석됨

   + Backbone의 $el 는 3세대 jQuery 라고 보면됨 

   + Functional programming이 가능 

   + Backbone -> AngularJS로 이동하면 된다 

  - Client + Server + Store 를 합치는 기술 = Meteor 또는 Derby 

  - MV* = Functional 이라는 개념으로 이동한다. 이것은 뷰가 모델이 되고, 컨트롤러가 없어지고, 나뉘었다 합쳐졌다하면서 데이터만 남는다. 즉, 과거 MVC 처럼 역할이 나뉘지 않는다

   


4) Contextual Level

  - 융합 서비스

  - Trend (500만) -> Culture (1000만) 즉, SNS를 통하여 트랜드나 문화로 가는 서비스 레벨

  - 데이터에 대한 MapReduce만 남는다 

    + Map = Key + Value 예) JSON

    + Reduce Function = Business Intelligence 솔루션으로 가는 것이다


결론, 기술 변천을 느끼고 만들어 가려면 Coding 하자.... ^^


<참조>

  - KOSTA : 이복영 강사, MongoDB/Node.js 강의 4주차 

posted by 윤영식
2013. 1. 31. 16:34 NodeJS/Concept

Node.js 에서 Express를 사용하면서 일관된 축약 언어 컴파일러로 JavaScript 코딩은 CoffeeScript를 사용하고, HTML은 Jade를 사용하고 CSS는 Stylus를 사용할 때 가장 기본적인 뼈대가 되는 코드를 만들어 주는 프레임워크 Cham을 알아보자. 


1) Cham 설치하기 

  - Node.js 와 NPM, CoffeeScript는 기본 설치되어 있어야 한다 

  - git clone 으로 설치하기 

$ git clone https://github.com/conancat/cham.git

Cloning into 'cham'...

remote: Counting objects: 155, done.

remote: Compressing objects: 100% (103/103), done.

remote: Total 155 (delta 48), reused 142 (delta 35)

Receiving objects: 100% (155/155), 136.89 KiB | 59 KiB/s, done.

Resolving deltas: 100% (48/48), done.


  - Express, jade, stylus 설치하기 

  - 설치후 브라우져 호출 : http://localhost:3000/ 

//////////////////////////////////////

// 설치 

$ cd cham

$ npm install express

npm http GET https://registry.npmjs.org/express/2.4.3

npm http 200 https://registry.npmjs.org/express/2.4.3

... 중략 ...

npm http 200 https://registry.npmjs.org/formidable

express@2.4.3 node_modules\express

├── mime@1.2.9

├── qs@0.5.3

└── connect@1.9.2 (formidable@1.0.11)


$ npm install jade

npm http GET https://registry.npmjs.org/jade

... 중략 ...

npm http 200 https://registry.npmjs.org/commander/-/commander-0.6.1.tgz

jade@0.28.1 node_modules\jade

├── commander@0.6.1

├── mkdirp@0.3.4

└── coffee-script@1.4.0


$ npm install stylus -g

npm http GET https://registry.npmjs.org/stylus

... 중략 ...

C:\Users\yuwonsystem01\AppData\Roaming\npm\stylus -> C:\Users\yuwonsystem01\AppD

ata\Roaming\npm\node_modules\stylus\bin\stylus

stylus@0.32.0 C:\Users\yuwonsystem01\AppData\Roaming\npm\node_modules\stylus

├── debug@0.7.0

├── mkdirp@0.3.4

└── cssom@0.2.5


$ npm install vows

npm http GET https://registry.npmjs.org/vows

npm http 200 https://registry.npmjs.org/vows

npm http GET https://registry.npmjs.org/vows/-/vows-0.7.0.tgz

... 중략 ...

npm http 200 https://registry.npmjs.org/diff/-/diff-1.0.4.tgz

vows@0.7.0 node_modules\vows

├── eyes@0.1.8

└── diff@1.0.4


///////////////////////////////////

// 실행하기 

$ node app

Express server listening on port 3000 in development mode



2) 구조파악하기 

  - root 폴더에 CakeFile이 존재하여 cake를 수행할 수 있다. (CoffeeScript 형태로 작성)

/////////////////////////////////////

// cake를 실행하면 사용법이 출력됨 

D:\git-nulpulum\cham>cake

Cakefile defines the following tasks:


cake watch             # Watches all Coffeescript(JS) and Stylus(CSS) files

cake watchJS         # Watches all coffeescript files for changes

cake watchCSS      # Watches all CSS files for changes

cake compileJS       # Compiles all Coffeescript files into JS

cake test                # Runs all tests

cake docs              # Create documentation using Docco


//////////////////////////////////////////////

// watch 하고 있는 원본 소스들을 볼 수 있다

// 원본 소스는 전부 src에 위치함

D:\git-nulpulum\cham>cake watch

15:10:11 - compiled src\lib\helpers.coffee

15:10:11 - compiled src\lib\module.coffee

15:10:11 - compiled src\lib\conf.coffee

15:10:11 - compiled src\test\testHelpers.coffee

15:10:11 - compiled src\public\js\plugins.coffee

15:10:11 - compiled src\app.coffee

15:10:11 - compiled src\test\example.test.coffee

15:10:11 - compiled src\lib\routes.coffee

15:10:11 - compiled src\public\js\script.coffee

  watching C:\Users\yuwonsystem01\AppData\Roaming\npm\node_modules\stylus\lib\functions\index.styl

  watching src\public\css\conf\base.styl

  watching src\public\css\conf\helpers.styl

  watching src\public\css\conf\colors.styl

  watching src\public\css\elems\reset.styl

  watching src\public\css\elems\helpers.styl

  watching src\public\css\elems\typography.styl

  watching src\public\css\elems\common.styl

  watching src\public\css\pages\layout.styl

  watching src\public\css\pages\index.styl

  watching src\public\css\media\media.styl

  compiled public\css\style.css

  watching src\public\css\style.styl

15:15:16 - compiled src\app.coffee       <== app.coffee 를 열어서 살짝 수정하였더니 자동으로 재컴파일 됨 


  - 의존관계 파악을 위해 package.json 파일을 열어보자 

{

  "name": "cham",

  "version": "0.0.1",

  "private": true,

  "dependencies": {

    "express": "2.4.3",

    "jade": ">= 0.0.1"

  },

  "devDependencies": {

    "vows": ">= 0.5.9",     // BDD 테스트

    "stylus": ">= 0.13.9",  // CSS

    "coffee-script": ">= 1.1.2" // Javascript 

  },

  "engines": {

    "node": "*"

  },

  "author": "Grey Ang <conancat@gmail.com> (http://grey-ang.com)",

  "description": "Boilerplate for quick Coffeescript driven app, backed by Jade and Stylus",

  "repository": {

    "type": "git",

    "url": "git://github.com/conancat/cham.git"

  },

  "scripts": {

    "test": "cake test"

  }

}


  - CoffeeScript 문법의 CakeFile : "task <명칭>, <설명>, -> 펑션"  task 다음에 3개의 아규먼트로 cake task 만듦

    + watchJS 명령 : coffee -cw -o ./ src/

    + watchCSS 명령 : stylus --watch --include ./public --out ./public/css ./src/public/css

    + compileJS 명령 : coffee -c -o ./ src/

    + test 명령 : vows test/*.test.js

    + docs 명령

       docco src/*.coffee

       docco src/lib/*.coffee

       docco src/test/*.coffee 

//////////////////////////////////////////
// CakeFile 내역 
# Module requires
{spawn, exec} = require 'child_process'
sys = require 'sys'

# ## Helpers

# Helper function for showing error messages if anyting happens
printOutput = (process) ->
  process.stdout.on 'data', (data) -> sys.print data
  process.stderr.on 'data', (data) -> sys.print data
  
# Watch Javascript for changes
watchJS = ->
  coffee = exec 'coffee -cw -o ./ src/'
  printOutput(coffee)

# Watch CSS for changes
watchCSS = ->
  
  # Without Nib
  stylus = exec 'stylus --watch --include ./public --out ./public/css ./src/public/css'
  
  # Use this line instead if you're using Nib
  # stylus = exec 'stylus --watch --include ./public --use ./node_modules/nib/lib/nib.js --out ./public/css ./src/public/css'
  
  printOutput(stylus)
  
# ## Tasks
# I guess pretty self explainory? lol
task 'watch', 'Watches all Coffeescript(JS) and Stylus(CSS) files', ->
  watchJS()
  watchCSS()

task 'watchJS', 'Watches all coffeescript files for changes', ->
  watchJS()
  
task 'watchCSS', 'Watches all CSS files for changes', ->
  watchCSS()
  
task 'compileJS', 'Compiles all Coffeescript files into JS', ->
 coffee = exec "coffee -c -o ./ src/"
 printOutput(coffee)
  
task 'test', 'Runs all tests', ->
  vows = exec 'vows test/*.test.js'
  printOutput(vows)
  
task 'docs', 'Create documentation using Docco', ->
  docco = exec """
    docco src/*.coffee
    docco src/lib/*.coffee
    docco src/test/*.coffee
  """
  printOutput(docco)



3) 사용한 모듈들 알아보기

  - Stylus

    + CSS를 축약해서 표현, 사용이 간단하고, 코드가 간결해짐 

    + ; 과 { } 를 사용할 필요가 없고  DRY (Don't Repeat Yourself) 지원


  - Docco

    + 주석을 MarkDown 으로 줄 수 있다 (GitHub README.md 만들기와 일관성 있어 좋군)

    + 수행한 위치 바로 밑에 docs 폴더에 위치함 

    + 설치 : npm install -g docco

    + 수행 : docco src/*.coffee


  - Jade

    + HTML 템플릿 엔진 : 이것도 < > 사용이 필요없어 코드가 간결해짐

    + 사용 설명


  - Vows

    + 비동기 BDD for Node

//////////////////////////////////////////
// vowtest.js
var vows = require('vows'),
    assert = require('assert');

// Create a Test Suite
vows.describe('Division by Zero').addBatch({
    'when dividing a number by zero': {
        topic: function () { return 42 / 0 },

        'we get Infinity': function (topic) {
            assert.equal (topic, Infinity);
        }
    },
    'but when dividing zero by zero': {
        topic: function () { return 0 / 0 },

        'we get a value which': {
            'is not a number': function (topic) {
                assert.isNaN (topic);
            },
            'is not equal to itself': function (topic) {
                assert.notEqual (topic, topic);
            }
        }
    }
}).run(); // Run it 

///////////////////////////////////////

// 결과 : 성공 

D:\git-nulpulum\cham>node vowtest.js

··· ✓ OK » 3 honored (0.036s)



  - Express

    + 설치 : npm install -g express

    + 수행 : $ express <projectName>

//////////////////////////////////////////
// Express로 Listen Server 구성
var express = require('express');
var app = express();

app.get('/', function(req, res){
  res.send('Hello World');
});

app.listen(3000);


  - CoffeeScript

    + 설치 : npm install -g coffee-script

    + 실행 : coffee <파일명>.coffee    <== .coffee 확장자 생략가능   



<참조> 

  - https://github.com/conancat/cham

'NodeJS > Concept' 카테고리의 다른 글

[Node.js] Express의 Connect 살펴보기  (0) 2013.03.11
[Node.js] 기술 발전 방향 4단계  (0) 2013.02.16
[Node.js] 생태계에 대한 생각들  (0) 2012.12.23
[Jade] Jade 사용하기  (0) 2012.12.15
[EJS] 사용하기  (0) 2012.12.15
posted by 윤영식

웹애플리케이션을 개발하기 위한 최신 기술셋을 알아보자. 모바일 컨버전스 솔루션 또는 서비스를 개발하기 위하여 방향전환을 시도중이다. 14년을 Java만 사용하다가 이제 다시 Reset 하는 기분으로 스터디중이랄까... 기본 언어가 자바스크립트이기 때문에 틈틈히 언어 공부도 필요하다. 하기 작성된 목록은 원문의 내용중 눈에 띄는 것을 임으로 정리한 것이다. 


1) Node.js 

  - 생태계가 잘 갖추어져 가고 있다 : modulesresources

  - 특징 : single-threaded, event-driven, asychronous I/O JavaScript Server Framework 

  - twitter list 팔로잉해서 최신 정보를 받자 

  - Logging, Error Handling, Bootup&Restart, Hosting 등의 해결책을 제시하고 있다 


2) JavaScript 

  - Node를 하려면 기본적으로 숙달해 있어야 한다 (JavaScript: The Definition Guide 추천 - 번역서 나왔음 6th)

  - DailyJS 통하여 최신 정보도 숙지한다 


3) CoffeeScript

  - .coffee 확장자로 코딩하여 .js로 컴파일 된다

  - 코드가 깔끔해 지고 유지보수성이 높아진다 

  - CoffeeScript의 스타일 가이드 참조 (참조2)

  - JavaScript를 CoffeeScript로 전환 툴

  - cake.coffee 툴 : CoffeeScript로 작성한 make 버전이다. CLI 방식 호출 (참조)


4) MongoDB

  - NoSQL : JSON방식 데이터 통신, 저장은 BSON(Binary JSON) 형태, JavaScript언어로 제어 

  - Replication Set 을 통한 High Availability 제공

  - Sharding을 통한 Scale-out을 제공

  - Aggregation Framework을 통하여 Big Data 제어 


5) Web Application 개발

  - Node에서는 Jade(Template Engine)사용, CSS는 stylus 사용함 

  - jQuery 기본 사용

  - UI MV* Framework으로 Backbone.js가 대세 - underscore.js를 기본사용함 -

  - Express : Node 에서 기본사용하는 MVC Framework - REST Web Services 개발함 - 


6) Testing 

  - Jasmine : BDD 

  - Vows : 비동기 BDD

  - QUnit : jQuery Javascript library


7) 통합 해주는 것들 

  - Express 개발할 때 : Express Wiki

  - CoffeeScript, Express, Jade, Stylus에 대한 boilerplate 코드 생성 : Cham

 

8) 추가적인 것들

  - socket.io : 실시간 구현

  - meteor : 실시간 서버 프레임워크 

  - 모바일 프레임워크 : PhoneGap


위의 내용들이 대충 눈에 들어오면 SKT의 CornerStone Framework을 내가 생각하는 모바일 컨버전스 솔루션이나 서비스에 접목 시켜 볼까 한다. 맨땅에 해딩하지 말고 이미 만들어진 것을 사용 목적에 맞게 수정하여 써보는 방향을 택한다. 실력이 된다면 기여자가 되보고 싶다. 



<참조>

  - 원문 : Getting Started With Node.js, Coffeescript, MongoDB, and More

posted by 윤영식
2013. 1. 30. 16:03 NodeJS/Prototyping

한개의 Socket.io 인스턴스를 공유하여 3개의 독립적인 채팅 서버를 운영하는 방법과 Express.js 사용시 virtual host를 설정하여 sub domain을 만드는 방법을 알아본다.



1. 가정

  - mydomain.com / sub1.mydomain.com / sub2.mydomain.com 의 서로 독립적인 채팅서버 운영

  - socket.io 인스턴스는 하나만 사용하여 공유함

  - 테스트 사이트 구경하기



2. GitHub에서 소스 다운로드

  - git 기본 설치 되었음을 가정한다 (참조)

  - 각 분리된 namespace에서 Chat 애플리케이션 3개의 인스턴스를 수행할 것이다

  - 소스 설치하기 

[mongodb@localhost ~]$ git clone git://github.com/braitsch/sub.socket.io.git socket-io-example

Initialized empty Git repository in /home/mongodb/socket-io-example/.git/

... 중략 ..

Resolving deltas: 100% (56/56), done.

[mongodb@localhost ~]$ cd socket-io-example/

[mongodb@localhost socket-io-example]$ pwd

/home/mongodb/socket-io-example


///////////////////////////////////////////

// 각 분리된 namespace 존재 

[mongodb@localhost socket-io-example]$ ls 

README.md  

mydomain.com 

sub1.mydomain.com  

sub2.mydomain.com



3. mydomain.com의 app.js 와 mydomain.com/subdomain/sub1(2).js 소스이해

  - Express 사용하기 

// app.js

var exp = require('express');

var app = exp.createServer();


  - socket.io Listen 설정 : 전역(gobal)으로 Socket.IO 인스턴스에 접근하도록 선언한다 

// app.js

// create the single instance of socket.io that will be shared across all applications //

// 한개의 socket.io인스턴스를 생성하여 모든 애플리케이션간 공유한다

global.socket = require('socket.io').listen(app);

global.socket.set('log level', 1);

global.socket.set('transports', [ 'websocket', 'flashsocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']);


  - subdomain 만들기

    + virtual host로써 동작하는 subdomain 애플리케이션을 설정한다

// create subdomain applications //

app.use(exp.vhost('sub1.' + global.host, require('./subdomains/sub1')));

app.use(exp.vhost('sub2.' + global.host, require('./subdomains/sub2')));


  - 모듈 로딩하면서 수행

// finally create this application, our root server //

// chat-socket.js 파일 모듈 로딩

require('./app/config')(app, exp);

require('./app/server/router')(app);

require('./app/server/modules/chat-socket');


  - sub1(2).js 소스 : 채팅 커넥션과 메세지를 다루기위해 chat-socket을 포함한 Express 애플리케이션이다

var exp = require('express');

var app = exp.createServer();


app.root = global.root + '/sub1.mydomain.com';

require(app.root + '/app/config')(app, exp);

require(app.root + '/app/server/router')(app);

require(app.root + '/app/server/modules/chat-socket');

module.exports = app;



4. chat-socket.js 소스이해

  - socket.io에 네임스페이스를 '/chat'으로 정의하기 

// pwd : ./socket-io-example/mydomain.com/app/server/modules

module.exports = function()

{

// 랜덤하게 사용자 색깔 지정 

var colors = ['#AE331F', '#D68434', '#116A9F', '#360B95', '#5F209E'];

        // 사용자 커넥션 추적을 유지하기 위한 객체 생성 

var connections = { };

// if you use socket.of(), you can set namespace. 

        // chat 네임스페이스 정의하고 connect  되면 수행할 펑션들 정의 

global.socket.of('/chat').on('connection', function(socket) {

       // give each connected user a random color so it's easier to tell them apart in the chat log //

               // 채팅사용자가 준비상태 

socket.on('user-ready', function(data) {

socket.name = data.name;

socket.color = data.color = colors[Math.floor(Math.random() * colors.length)];

brodcastMessage('user-ready', data);

});


               // 메세지 전송하기 

socket.on('user-message', function(data) {

data.color = socket.color;

brodcastMessage('user-message', data);

});


                // 접속자 상태 전송 

function dispatchStatus()

{

brodcastMessage('status', connections);

}

                // 메세지 전송하기 

function brodcastMessage(message, data)

{

               // remove socket.emit if you don't want the sender to receive their own message //

socket.emit(message, data);

socket.broadcast.emit(message, data);

}

                // soket.io 커넥션 끊길 때 호출 

        // handle connections & disconnections //

connections[socket.id] = {}; dispatchStatus();

socket.on('disconnect', function() {

delete connections[socket.id]; dispatchStatus();

brodcastMessage('user-disconnected', { name : socket.name, color : socket.color });

});

});

}();


  - sub1.mydomain.com 에 대하여 네임스페이스를 틀리게 기술한다 

global.socket.of('/chat-sub1').on('connection', function(socket) ...


  - sub2.mydomain.com 에 대하여 네임스페이스를 틀리게 기술한다 

global.socket.of('/chat-sub2').on('connection', function(socket) ...



5. index.js와 index.jade 소스이해

  - index.jade 하단에 index.js 와 socket.io.js 포함 

div.navbar.navbar-fixed-top

div.navbar-inner

div.container-fluid

ul.nav.pull-left

.brand Node.js & Socket.IO Chat Server

ul.nav.pull-right

li

a(href='#')#connected


#container

#send-message.well.span4

h2 Say Something

hr

label Your Name 

input(type="text", name="name", id='name').span4

label Your Message

textarea(rows='6', name="msg", id='msg').span4

button#btn-send.btn.btn-primary

i.icon-pencil.icon-white

| Send it !

#messages.well.span4

h2 Conversation

hr

#incoming


script(src='/vendor/jquery.min.js')

script(src='/socket.io/socket.io.js')

script(src='/js/index.js')


  - index.js 파일

$(document).ready(function() {


$('#msg').focus();

        // give user a generic name to start //

        // 사용자가 접속하면 랜덤 명칭을 설정한다 

$('#name').val(Math.random().toFixed(8).toString().substr(2));

$('#btn-send').click(function(){ sendMessage(); })

$('#msg').keypress(function(e){ if (e.keyCode === 13) { sendMessage(); return false; } })


       // initialize the socket connection to listen on the 'chat' namespace //

socket = io.connect('/chat');

socket.on('status', function (connections) {

var i=0; for (p in connections) i++;

var s = i > 1 ? ' are '+i+' People ' : ' is '+i+' Person ';

$('#connected').html('There '+s+' Currently Connected');

});

socket.on('user-ready', function (data) {

$('#incoming').append('<span class="shadow" style="color:'+data.color+'">'+data.name +' :: connected</span><br>');

autoScroll();

});

socket.on('user-message', function (data) {

$('#incoming').append('<span class="shadow" style="color:'+data.color+'">'+data.name +' :: '+ data.message+'</span><br>');

autoScroll();

});

socket.on('user-disconnected', function (data) {

$('#incoming').append('<span class="shadow" style="color:'+data.color+'">'+data.name +' :: disconnected</span><br>');

autoScroll();

});


        // register the user's name with the socket connection on the server // 

socket.emit('user-ready', {name : $('#name').val() });

var autoScroll = function() { 

document.getElementById('incoming').scrollTop = document.getElementById('incoming').scrollHeight; 

}


        // 메세지 보내기 

var sendMessage = function() {

socket.emit('user-message', {name : $('#name').val() , message : $('#msg').val() });

$('#msg').val('')

}

});



7. 채팅 서비스 설정하기 

  - 채팅 서비스에 대한 수행전에 필요한 모듈에 대해서 install 한다 

///////////////////////////////////////////////////////////////

// mydomain.com 에 stylus, jade, express, socket.io 설치

// package.json 참조하여 설치함

$ cd mydomain.com 

$ npm install -d 

... 중략 ...

stylus@0.32.0 node_modules/stylus

jade@0.28.1 node_modules/jade

express@2.5.8 node_modules/express

socket.io@0.9.13 node_modules/socket.io

npm info ok 


// mydomain.com 안에 모듈 설치 디렉토리 생성

[mongodb@localhost mydomain.com]$ ll
total 20
drwxrwxr-x. 4 mongodb mongodb 4096 Feb  1 23:17 app
-rw-rw-r--. 1 mongodb mongodb 1109 Feb  1 23:17 app.js
drwxrwxr-x. 7 mongodb mongodb 4096 Feb  2 19:49 node_modules
-rw-rw-r--. 1 mongodb mongodb  590 Feb  1 23:17 package.json
drwxrwxr-x. 2 mongodb mongodb 4096 Feb  1 23:17 subdomains

//////////////////////////////////////////////////////
// sub1/sub2 도메인에 jade, stylus, express 설치 
// (socket.io는 mydomain에만 설치됨)
$ cd ../sub1.mydomain.com
$ npm install -d 
... 중략 ...
npm info prepublish sub.socket.io@1.0.0
jade@0.28.1 node_modules/jade
stylus@0.32.0 node_modules/stylus
express@2.5.8 node_modules/express


  -  /etc/hosts 파일에 다음을 설정한다 : 브라우져에서 호출하기 위한 sub1, sub2 도메인을 설정한다 

127.0.0.1 sub1.localhost

127.0.0.1 sub2.localhost



8. Chat Node Server 실행하기

  - mydomain.com 디렉토리로 들어가서 Node를 실행한다

/home/mongodb/socket-io-example/mydomain.com

[mongodb@localhost mydomain.com]$ node app

   info  - socket.io started

Express server listening on port 8080 in development mode 


  - 브라우져 2개를 띄워서 http://localhost:8080 을 동일하게 실행한다 

    + dowon 채팅창과 다른 브라우져창에서 try 명칭의 사용자가 들어왔다

    + socket.io를 통하여 채팅을 주고 받고 있다


  - 브라우져 2개를 띄워서 http://sub1.localhost:8080 을 동일하게 실행한다 (http://sub2.localhost:8080 동일 수행함)

    + youngsik 채팅창과 다른 브라우져창에서 girl 명칭의 사용자가 들어왔다

    + mydomain.com의 동일한 socket.io를 통하여 채팅을 주고 받고 있다 (namespace만 틀릴 뿐이다)



<참조>

  - 원문 : Building a Node.js Chat Application and Sharing Socket.IO Across Multiple Subdomains

  - 소스 : https://github.com/braitsch/sub.socket.io

  - Express.js Virtual Host 설정

  - 원문과 동일한 socket.io 인스턴스 한개와 Virtual Host 를 통한 SubDomain 공유에 대한 동일 예제


posted by 윤영식
2013. 1. 29. 21:57 NodeJS/Prototyping

Node.js를 설치하고 MongoDB를 사용하여 REST API를 만들어보자. native MongoDB driver를 사용하며 REST API를 쉽게 만들기 위하여 Node.js의 웹애플리케이션 프레임워크인 Express를 이용한다. 원문의 내용을 보고 수행한 결과를 요약한다 



1) Node.js 설치 

  - http://nodejs.org/dist/  : 사이트에서 최신 버전을 선택하여 다운로드한다 

  - 예) linux 

[mongodb@localhost ~]$ wget http://nodejs.org/dist/v0.9.8/node-v0.9.8-linux-x86.tar.gz 

--2013-02-01 21:24:48--  http://nodejs.org/dist/v0.9.8/node-v0.9.8-linux-x86.tar.gz

Resolving nodejs.org... 165.225.133.150

Connecting to nodejs.org|165.225.133.150|:80... connected.

HTTP request sent, awaiting response... 200 OK

Length: 4491882 (4.3M) [application/octet-stream]

Saving to: “node-v0.9.8-linux-x86.tar.gz”


100%[=========================================================>] 4,491,882    284K/s   in 17s     


2013-02-01 21:25:07 (263 KB/s) - “node-v0.9.8-linux-x86.tar.gz” saved [4491882/4491882]


[mongodb@localhost ~]$ ls

aggregation  mongo  mongod  mongodb  mongofiles  mongos  node-v0.9.8-linux-x86.tar.gz  shard

[mongodb@localhost ~]$ tar zxf node-v0.9.8-linux-x86.tar.gz

[mongodb@localhost ~]$ ls

aggregation  mongod   mongofiles  node-v0.9.8-linux-x86         shard

mongo        mongodb  mongos      node-v0.9.8-linux-x86.tar.gz

[mongodb@localhost ~]$ rm node-v0.9.8-linux-x86.tar.gz

[mongodb@localhost ~]$ mv node-v0.9.8-linux-x86 node-v0.9.8

[mongodb@localhost ~]$ ls

aggregation  mongo  mongod  mongodb  mongofiles  mongos  node-v0.9.8  shard

[mongodb@localhost ~]$ cd node-v0.9.8/

[mongodb@localhost node-v0.9.8]$ cd bin

[mongodb@localhost bin]$ ./node -v

v0.9.8


2) Node.js 수행하기 

  - 적당한 디렉토리에 nodecellar 디렉토리 만듦

  - nodecellar 안에 server.js 파일 생성

  - server.js 코딩 

////////////////////////////////////////////////
// server.js
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(3000, '127.0.0.1');
console.log('Server running at http://127.0.0.1:3000/');


  - server.js 수행하고 브라우져에서 http://127.0.0.1:3000/ 호출 

[mongodb@localhost ~]$ cd nodecellar/

[mongodb@localhost nodecellar]$ node server.js

Server running at http://127.0.0.1:3000/



3) Express 설치하기 

  - Node.js의 Web Application Framework 이고, REST API 생성을 쉽게 해준다 

  - nodecellar 디렉토리안에 package.json 파일을 만들어서 Node.js가 의존하는 모듈을 정의한다 

////////////////////////////////////////////
// package.json
{
    "name": "wine-cellar",
    "description": "Wine Cellar Application",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
        "express": "3.x"
    }
}

  - express 설치하기 

// package.json의 의존관계 모듈을 읽어서 자동 설치해 준다 

[mongodb@localhost nodecellar]$ npm install

npm WARN package.json wine-cellar@0.0.1 No README.md file found!

npm http GET https://registry.npmjs.org/express

npm http 200 https://registry.npmjs.org/express

npm http GET https://registry.npmjs.org/express/-/express-3.1.0.tgz

... 중략 ...
express@3.1.0 node_modules/express
├── methods@0.0.1
├── fresh@0.1.0
├── range-parser@0.0.4
├── cookie-signature@0.0.1
├── buffer-crc32@0.1.1
├── cookie@0.0.5
├── commander@0.6.1
├── debug@0.7.0
├── mkdirp@0.3.3
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.2 (pause@0.0.1, bytes@0.1.0, formidable@1.0.11, qs@0.5.1)



4) server.js를 Express 형식으로 바꾸기 

  - express 프레임워크를 이용하여 HTTP Listener를 바꾼다

////////////////////////////////////////////
// server.js
var express = require('express');
 var app = express();
 
app.get('/wines', function(req, res) {
    res.send([{name:'wine1'}, {name:'wine2'}]);
});
app.get('/wines/:id', function(req, res) {
    res.send({id:req.params.id, name: "The Name", description: "description"});
});
 
app.listen(3000);
console.log('Express Listening on port 3000...');

  - express 실행

[mongodb@localhost nodecellar]$ node server

Express Listening on port 3000...


  - 브라우져 호출하기 

    + 전체 wine들 

  

    + 1번 wine 내역 

  


5) Node.js에서 Controller로써 routes를 만들기 

  - nodecellar 디렉토리 밑으로 routes 폴더를 만든다 

  - routes 밑에 모듈로 wines.js 를 만든다 

////////////////////////////////////////////
// routes 디렉토리 밑의 wines.js
exports.findAll = function(req, res) {
    res.send([{name:'wine1'}, {name:'wine2'}, {name:'wine3'}]);
};
 
exports.findById = function(req, res) {
    res.send({id:req.params.id, name: "The Name", description: "description"});
};


  - server.js 파일에서 wines.js 모듈을 로딩하게 한다. 그리고 다시 브라우져로 호출한다 

////////////////////////////////////////////
// server.js에서 wines.js 모듈 로딩
var express = require('express'),
    wines = require('./routes/wines');
var app = express();
 
app.get('/wines', wines.findAll);
app.get('/wines/:id', wines.findById);
 
app.listen(3000);
console.log('Express Listening on port 3000...');


6) MongoDB Driver 설치하기 

  - MongoDB는 설치되어 있다고 가정한다 (참조)

  - 여기서는 native Node.js driver를 사용한다

  - mongodb driver 설치하기 

[mongodb@localhost nodecellar]$ npm install mongodb

npm WARN package.json wine-cellar@0.0.1 No README.md file found!

npm http GET https://registry.npmjs.org/mongodb

...  중략 ...

npm http GET https://registry.npmjs.org/bson/-/bson-0.1.6.tgz

... 중략 ...

node-gyp clean

node-gyp configure build

gyp http GET http://nodejs.org/dist/v0.9.8/node-v0.9.8.tar.gz

gyp http 200 http://nodejs.org/dist/v0.9.8/node-v0.9.8.tar.gz

make[1]: Entering directory `/home/mongodb/nodecellar/node_modules/mongodb/node_modules/bson/build'

  CXX(target) Release/obj.target/bson/ext/bson.o

  SOLINK_MODULE(target) Release/obj.target/bson.node

  SOLINK_MODULE(target) Release/obj.target/bson.node: Finished

  COPY Release/bson.node

make[1]: Leaving directory `/home/mongodb/nodecellar/node_modules/mongodb/node_modules/bson/build'

child process exited with code 0

mongodb@1.2.11 node_modules/mongodb

└── bson@0.1.6



7) REST API 정의하기 

  - 호출 내역 

    + GET: 전체 wine 목록

    + GET: id로 선택된 wine 정보얻기 

    + POST: 새로운 wine 생성

    + PUT: id로 선택된 wine 정보갱신

    + DELETE: id로 선택된 wine 삭제하기 

  

  

  - server.js에서 wines.js를 확장한 메소드를 추가한다 

  - wines.js 안에 MongoDB 코드로 변경하기 



8) MongoDB 와 Node.js 수행하고 Testing 하기 

  - MongoDB는 default port로 수행한다 

[mongodb@localhost ~]$ ./mongod --dbpath /home/mongodb/aggregation

... 중략 ...

Fri Feb  1 22:30:46 [initandlisten] options: { dbpath: "/home/mongodb/aggregation" }

Fri Feb  1 22:30:46 [initandlisten] Unable to check for journal files due to: boost::filesystem::basic_directory_iterator constructor: No such file or directory: "/home/mongodb/aggregation/journal"

Fri Feb  1 22:30:46 [initandlisten] couldn't unlink socket file /tmp/mongodb-27017.sockerrno:1 Operation not permitted skipping

Fri Feb  1 22:30:46 [initandlisten] waiting for connections on port 27017

Fri Feb  1 22:30:46 [websvr] admin web console waiting for connections on port 28017



  - Node.js 수행하기 

     + MongoDB의 기본 port 27017 로 접근한다 

[mongodb@localhost nodecellar]$ node server

========================================================================================

=  Please ensure that you set the default write concern for the database by setting    =

=   one of the options                                                                 =

=                                                                                      =

=     w: (value of > -1 or the string 'majority'), where < 1 means                     =

=        no write acknowlegement                                                       =

=     journal: true/false, wait for flush to journal before acknowlegement             =

=     fsync: true/false, wait for flush to file system before acknowlegement           =

=                                                                                      =

=  For backward compatibility safe is still supported and                              =

=   allows values of [true | false | {j:true} | {w:n, wtimeout:n} | {fsync:true}]      =

=   the default value is false which means the driver receives does not                =

=   return the information of the success/error of the insert/update/remove            =

=                                                                                      =

=   ex: new Db(new Server('localhost', 27017), {safe:false})                           =

=                                                                                      =

=   http://www.mongodb.org/display/DOCS/getLastError+Command                           =

=                                                                                      =

=  The default of no acknowlegement will change in the very near future                =

=                                                                                      =

=  This message will disappear when the default safe is set on the driver Db           =

========================================================================================

Express Listening on port 3000...

Connected to 'winedb' database


  - curl을 수행한다 

/////////////////////////////////////////

// POST를 통하여 신규 wine을 생성한다

[mongodb@localhost ~]$ curl -i -X POST -H 'Content-Type: application/json' -d '{"name": "New Wine", "year": "2009"}' http://localhost:3000/wines

HTTP/1.1 200 OK

X-Powered-By: Express

Content-Type: application/json; charset=utf-8

Content-Length: 79

Date: Sat, 02 Feb 2013 06:38:49 GMT

Connection: keep-alive


{

  "name": "New Wine",

  "year": "2009",

  "_id": "510cb4798859a9b51d000001"


/////////////////////////////////////////

// MongoDb 확인 

[mongodb@localhost ~]$ mongo

MongoDB shell version: 2.2.2

connecting to: test

> show dbs

dowonDB 0.03125GB

local (empty)

winedb 0.0625GB

> use winedb

switched to db winedb

> show collections

system.indexes

wines

> db.wines.find()

{ "name" : "New Wine", "year" : "2009", "_id" : ObjectId("510cb4798859a9b51d000001") }


/////////////////////////////////////////

// GET 명령 수행하여 정보 조회

// wine 목록을 얻어온다.

[mongodb@localhost ~]$ curl -i -X GET http://localhost:3000/wines

HTTP/1.1 200 OK

X-Powered-By: Express

Content-Type: application/json; charset=utf-8

Content-Length: 93

Date: Sat, 02 Feb 2013 06:41:37 GMT

Connection: keep-alive


[

  {

    "name": "New Wine",

    "year": "2009",

    "_id": "510cb4798859a9b51d000001"

  }

]


// 특정 wine 조회. _id를 넣어준다 

[mongodb@localhost ~]$ curl -i -X GET http://localhost:3000/wines/510cb4798859a9b51d000001

HTTP/1.1 200 OK

X-Powered-By: Express

Content-Type: application/json; charset=utf-8

Content-Length: 79

Date: Sat, 02 Feb 2013 06:42:14 GMT

Connection: keep-alive


{

  "name": "New Wine",

  "year": "2009",

  "_id": "510cb4798859a9b51d000001"



/////////////////////////////////////////

// PUT 명령 수행하여 정보 수정 

[mongodb@localhost ~]$ curl -i -X PUT -H 'Content-Type: application/json' -d '{"name": "New Wine", "year": "2010"}' http://localhost:3000/wines/510cb4798859a9b51d000001
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 42
Date: Sat, 02 Feb 2013 06:44:00 GMT
Connection: keep-alive

{
  "name": "New Wine",
  "year": "2010"


/////////////////////////////////////////

// DELETE 명령 수행하여 정보 삭제

[mongodb@localhost ~]$ curl -i -X DELETE http://localhost:3000/wines/510cb4798859a9b51d000001
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 2
Date: Sat, 02 Feb 2013 06:46:22 GMT
Connection: keep-alive

/////////////////////////////////////////

// MongoDb 확인 

[mongodb@localhost ~]$ mongo
MongoDB shell version: 2.2.2
connecting to: test
> use winedb
switched to db winedb
> show collections
system.indexes
wines
> db.wines.find()    <=== 데이터가 삭제되어 없음 



<참조>

  - 원문 : Creating a REST API using Node.js, Express, and MongoDB

  - 참조 

    + https://speakerdeck.com/jakobmattsson/writing-restful-web-services-using-nodejs

    + Node.js 설치하기

    + MongoDB 설치하기

  - 심화 : Backbone.js 와 Bootstrap, Node.js로 만들기 

posted by 윤영식
2012. 12. 10. 17:22 NodeJS/Concept

전역범위에서 참조가 가능한 글로벌 오브젝트. already defined object라고 할 수 있겠다. 



global objects 
> 하기 객체는 모든 모듈에서 이용할 수 있다. 실제 전역 범위를 가진다 
> node에서 var something의 something은 지역범위만 갖는다 
> global : {Object} 전역 네임스페이스 객체 
> process, console : {Object}
> Class: Buffer : {Function} 바이너리 데이터를 다루는데 사용 
> require() : 모듈 로딩으로 지역범위임
> __filename : {String} 실행되는 코드의 파일명 (코드의 절대경로 포함)
> __dirname : {String} 현재 실행되는 스크립트가 존재하는 디렉토리 경로 
> module : {Object} 현재 모듈에 대한 참조. 특히 module.exports는 exports 객체와 같다 
> exports : require()로 접근가능하게 된 모듈의 모든 인스턴스 사이에서 공유되는 객체다. 
> setTimeouts(cb, ms) : cb=callback, ms=milliseconds
  clearTimeout(t) : setTimeout()올 생성된 타이머를 멈춘다
> setInterval(cb, ms) : 반복적으로 callback 수행
  clearInterval(t)


>> fileName : globalTest.js

console.log(__filename);

console.log(__dirname);


>> 수행 

D:\Framework\Node.js> node globalTest

D:\Framework\Node.js\globalTest.js

D:\Framework\Node.js


'NodeJS > Concept' 카테고리의 다른 글

[Jade] Jade 사용하기  (0) 2012.12.15
[EJS] 사용하기  (0) 2012.12.15
[Node.js] File I/O 사용하기  (0) 2012.12.10
[Node.js] EventEmitter 에 대하여  (0) 2012.12.10
[Node.js] debugger 사용하기  (0) 2012.12.10
posted by 윤영식
prev 1 2 next