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

Publication

Category

Recent Post

2012. 12. 23. 01:40 NodeJS/Concept

Node.js를 리안달이 만들고 난후 프로그래밍의 패러다임이 바뀌고 있다. 스타트업을 위한 모바일 서비스 또는 솔루션의 기본 플랫폼으로 사용되고 있다. 특히 요즘은 Client + Server + DB 가 인터넷에서 하나로 연결되고 있다. 인터넷이 하나의 운영체제처럼 변해가고 있는 것이다. 


  - JavaScript : Client + Server + DB 프로그래밍을 할 수 있는 랭귀지로 자리 잡고 있다.

  - JSON : MongoDB를 사용하면 Client + Server + DB 를 하나의 데이터로 통일 할 수 있다.

  - Socket.io : 인터넷에 물려있는 모든 Tier의 통신을 HTTP 프로토콜을 통하여 Bi-Direction 양방향 통신을 할 수 있다.


1) 인터넷에 연결된 모든 부분이 JSON을 통하여 데이터를 주고 받는다.


2) Node.js 생태계에 나타난 Framework들 : Realtime쪽에는 전부 Socket.io 가 핵심 모듈로 사용되고 있다.  

  - Backbone에서 본 현재 현황



3) Node.js 소개 + 코딩 + 클라우드 파운드리 


4) Derby 와 Meteor 비교 


5) Node에서도 TDD 개발은 중요하다. Node위에서 Server Side JavaScript 개발을 할 때 Vows와 Twitter를 이용한다.(24page)



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

[Node.js] 기술 발전 방향 4단계  (0) 2013.02.16
[Cham] Express, CoffeeScript, Jade, Stylus boilerplate 코드 생성하기  (0) 2013.01.31
[Jade] Jade 사용하기  (0) 2012.12.15
[EJS] 사용하기  (0) 2012.12.15
[Node.js] Global Objects  (0) 2012.12.10
posted by 윤영식
2012. 12. 22. 17:42 NodeJS/Prototyping

socket.io를 이용하여 간단한 chatting 애플리케이션을 만들어 보자 


* 참조 : socket.io이용하여 chat 구현하기


> Express를 통하여 chat 컨텍스트를 만든다 (참조)

express chat


> app.js 에 socket.io를 위한 /chat 네임스페이스를 설정하고(jade이용), socket.io에 대하여 설정한다

// declaration

var express = require('express');

var app = express()

    , http = require('http').createServer(app)

    , io = require('socket.io').listen(http)

    , routes = require('./routes')

    , user = require('./routes/user')

    , chat = require('./routes/chat')

    , path = require('path');


app.get('/chat', chat.list);


// http listen

http.listen(app.get('port'), function(){

    console.log("Express server listening on port " + app.get('port'));

});


// socket connection event on

var chat = io

    .of('/chat')

    .on('connection', function(socket) {  // /chat uri로 접속이 들어오는 이벤트 처리 

        console.log('>>> chat server connection');


        socket.on('msg', function(data) { // msg 이벤트 처리 

            console.log('>>> data : ' + data.name + ', ' + data.msg);

            chat.emit('new', data); // new 이벤트를 발행하여 data를 다시 클라이언트들에게 전송 

        });

})


> jade 관련 파일 : chat.js 와 chat.jade 

// /routes 디렉토리의 chat.js 파일

exports.list = function(req, res){

    res.render('chat', { title: 'Chatting Example' });

};


//  /views 디렉토리의 chat.jade 파일

doctype 5

html

  head

    title= title

    link(rel='stylesheet', href='/stylesheets/style.css')

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

    script(src='http://code.jquery.com/jquery-1.8.3.min.js')

    script(src='chat_module.js')

  body

    h1= title

    div#wrapper

        div#messages  // chat 메세지가 찍힌다 

        div.nic

            input#name(name='name', type='text')  // 이름 입력 창

        div

        textarea#message  // 메세지 입력 창

        br

        input#send(type='submit', value='Send')

    // chat_module.js에서 Chat 오브젝트를 초기화 한다 

    script

        $(document).ready(function() {

            Chat.initialize('/chat');

        });


> chat_module.js 안에 로직을 담는다 : 해당 모듈은 express의 public 디렉토리 밑에 놓는다 (즉시 실행 함수로 만듦)

(function() {

    window.Chat = {

      socket : null,


     // 초기화 시에 /chat uri 네임스페이스를 넣어주었다 

      initialize : function(socketURL) {

          console.log('step1 socketURL : %s', socketURL);

          this.socket = io.connect(socketURL);


          console.log('step2 conneciton ok : %s ', this.socket);


   // send 버튼을 누를 경우 실행 

          $('#send').click(function() {

              Chat.send();

          });


    // textarea 메세지 입력하고 enter key 칠 경우 

          $('#message').keyup(function(evt) {

             if((evt.keyCode || evt.which) == 13) {

                 Chat.send();

                 return false;

             }

          });


          // 서버로 부터 new 이벤트가 오면 메세지를 추가하는 add 콜백 설정  

          this.socket.on('new', this.add);

      },


      // 서버로 부터 발행된 new 이벤트 처리하는 펑션

      add : function(data) {

          console.log('add message : %s', data.name +', '+ data.msg);

          var name = data.name || 'anonymous';

          var msg = $('<div class="msg"></div>')

              .append('<span class="name">' + name + '</span>: ')

              .append('<span class="text">' + data.msg + '</span>');

          console.log('add html : %s', msg);


          $('#messages').append(msg).animate({scrollTop: $('#messages').prop('scrollHeight')}, 0);

      },


      // 메세지 넣고 send 버튼을 클릭할 때 수행하는 펑션 

      send : function() {

          console.log('sending message : %s', $('#name').val() +', '+ $('#message').val());

          this.socket.emit('msg', {

              name: $('#name').val(),

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

          });


          $('#message').val('');

      }

    };

}());



> node app 명령으로 Node 서버를 실행시킨 후 브라우저로 호출한다 (http://localhost:3000/chat)

youngsik과 dowon 끼리 대화하는 것을 서버가 전송하고 있다 


* Express + Jade + Socket.io 프로젝트 파일 전체  

chat.zip


* js 파일이 변경될 때 마다 Node.js를 restart 하고 싶지 않다면 supervisor를 사용한다 

posted by 윤영식
2012. 12. 22. 14:46 NodeJS/Prototyping

Node.js에서 Express.js를 사용하고 템플릿 엔진은 Jade를 사용한다. 이때 socket.io를 간단히 테스트 해보자 


> 먼저 Socket.io 모듈를 설치한다 (물론 express 모듈도 사전 설치되었다 가정한다)

npm install socket.io


> Express.js를 통하여 만들고자 하는 컨텍스트를 만든다

express day3


> day3 디렉토리로 이동을 하면 app.js 파일이 있고 해당 파일안에 socket.io 모듈를 넣고 http 모듈과 체인닝을 해준다. 그리고 jade 설정이 되어 있는 socketio.js 모듈을 로딩한다 

// app.js 파일 상단 코딩

// 기존 코드 

var express = require('express')

  , routes = require('./routes')  // index.js 파일 

  , user = require('./routes/user') // user.js 파일 

  , dowon = require('./routes/dowon')// dowon.js 파일 

  , http = require('http')

  , path = require('path');


// 변경 코드 

var express = require('express');

var app = express()

  , http = require('http').createServer(app)   

  , io = require('socket.io').listen(http)  // http 모듈을 socket.io 모듈과 체인닝함 

  , routes = require('./routes')

  , user = require('./routes/user')

  , socketio = require('./routes/socketio') // socketio.js 파일 로딩 

  , path = require('path');


> url rout 설정을 해줌 for jade

// url route

app.get('/', routes.index);

app.get('/users', user.list);

app.get('/socketio', socketio.io); //  브라우져에서 /socketio 호출하면 socketio 모듈의 io exports명칭의 펑션을 호출한다


> socketio.jade 파일을 만들어서 views 디렉토리에 놓는다 

// socketio.jade 파일 내역

doctype 5

html

  head

    title= title

    link(rel='stylesheet', href='/stylesheets/style.css')

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

    script(src='http://code.jquery.com/jquery-1.8.3.min.js')

    script

        $(function() {

            var ws = io.connect();  // node에서 수행한 app.js의 socket.io listen으로 연결


            ws.emit('server_1');  // 서버쪽으로 server_1 이벤트 발행

            ws.on('client_1', function(msg) {  // 서버로부터 온 client_1 이벤트 처리 

                $('#container').html(msg);

            });

        });

  body

    h1= title

    div#container


> app.js 파일안에 socket.io 서버 코딩을 한다

// socket on

io.sockets.on('connection', function(socket) {

    console.log('server connection');


    socket.on('server_1', function(data) { // 클라이언트로 부터 온 server_1 이벤트 처리

        if(data != undefined) {

            console.log('>>>>>' + data);

        }


        var msg = 'hi youngsik';

        socket.emit('client_1', msg); // 클라이언트쪽으로 client_1 이벤트 발행

    });

});


> 브라우저에서 호출한다 그러면 잠시후 브라우져에서 "hi youngsik" 메세지가 div(id=container)에 뿌려진다


* 테스트 전체 파일

express_socketio.zip


* Socket.io GitHub : 자세한 사용 설명 보기

posted by 윤영식
2012. 12. 21. 16:18 Languages/JavaScript

렌더링 과정에 대하여 알아보고, 렌더링시 성능 최적화할 수 있는 방법들을 살펴보자 (책. 4장 렌더링)



▶ 전체 브라우저 렌더링 처리 과정


  - 전체 브라우저 처리과정 : HTML DOM 트리 + CSS 스타일 구조체 = 렌더 트리 생성 (레이아웃 처리) -> 페인트 (화면에 표현)

  - DOM 트리 생성 : HTML을 DOM 요소 노드 트리 형태로 구성.

  - 스타일 구조체 생성 : CSS 정보를 스타일 구조체(Style Struct)로 생성한다. 

  - 렌더 트리 생성 : DOM 트리와 각 노드에 스타일 정보를 설정하여 화면에 표현할 노드로 구성한다. DOM 트리와 렌더 트리는 1:1 대응하지 않는다.

  - 레이아웃 처리 : 렌더 트리의 각 노드 크기가 계산되어 위치계산한다.

  - 페인트(Paint) : 렌더 트리를 순회하면서 페인트 함수를 호출해 노드를 화면에 표현한다.



▶ 리플로와 페인트


  - 리플로(Reflow) : Ajax와 같은 데이터를 가져와서 화면에 뿌릴라 치면 변경이 필요한 렌더 트리에 대한 유효성 확인 작업과 함께 노드의 크기와 위치를 다시 계산한다. 이과정을 리플로 = 레이아웃(Layout) = 레이아웃팅(Layouting)  이라 한다. (부모 노드의 변경은 자식 노드 변경 리플로도 야기한다)

  - 리페인트(Repaint) : 변경 영역의 결과를 표현하기 위해 화면이 업데이트 되는 것을 의미한다. 리페인트 = 리드로(Redraw) 

  - 리플로 와 리페인트는 비용이 높다. 발생하는 원인을 살펴보자 

    + DOM 노드의 변경 : 추가, 삭제

    + DOM 노드 노출 속성을 통한 변경 : 추가, 삭제, 특성 변경

    + 스크립트 애니메이션 : 애니메이션은 DOM, 스타일 등이 짧은 시간에 수차례 변경되는 것임

    + 스타일 : 추가, 변경

    + 사용자 액션 : 브라우저 크기 변경, 글꼴 크기 변경등 



▶ 리플로 & 페인트 최소화 방법


  - 작업 그룹핑 : DOM 요소 변경시 같은 형태끼리 그룹으로 묶어서 실행한다. 

  - 실행 사이클 : 루핑 구문 즉 setTimeOut같은 구문에서 DOM 요소 핸들링을 배제한다.

  - display 속성 : 루핑이 어쩔 수 없다면 

element.style.display="none"; 

<looping구문> 

element.style.display="block";  


  - 이렇게 하면 루핑구문에서 "리플로+페인트"가 계속 발생하지 않고, none과 block 할때 딱 두번만 발생한다.

  - 노드 복제 : 루핑도는 구문에서 노드 핸들링시 원복 노드를 복제하여 사용함 

var clone = element.cloneNode(true);

<looping 구문>

parentNode.replaceChild(clone, element);


  - createDocumentFragment() 사용 : DOM 객체와 별개의 새로운 DOM 객체를 생성하여 사용하면 렌더링 성능 향상 가능함.

var fragment = document.createDocumentFragment(); 

<looping 구문안에서 fragment.appendChile(elems[e]); 호출 > 


  - 캐싱 : 별도의 변수에 자주 사용하는 속성값 또는 메소드값을 저장하여 사용한다. 

  - 하드웨어 가속 렌더링 : GPU를 이용한다. 브라우져 마다 설정값이 틀림. (크롬 :  chrome://flags 로 GPU 설정 확인 가능)


posted by 윤영식
2012. 12. 21. 11:31 Git, GitHub/Git Lec01

Git 내부 저장소를 최적화 해주는 작업과 zip/tar로 묶는 방법에 대해 알아보자 


  • git gc : 저장소의 크기 압축 및 최적화 (지저분한 내용을 정리)
  • git gc --aggressive : 변경 사항 델타(delta)단위로 저장한다. 저장단위를 처음부터 최적화 한다 
$ git gc
Counting objects: 201, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (123/123), done.
Writing objects: 100% (201/201), done.
Total 201 (delta 57), reused 193 (delta 54)

$ git gc --aggressive
Counting objects: 201, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (177/177), done.
Writing objects: 100% (201/201), done.
Total 201 (delta 61), reused 140 (delta 0)



  • git archive --format=zip --prefix=aa/ HEAD > bb.zip : zip 포멧으로 aa/ 디렉토리 밑으로 모든 파일을 넣어서 HEAD에서 압축 생성하여 bb.zip파일을 만든다 
  • git archive --format=tar --prefix=aa/ HEAD | gzip > bb.tar.gz : 상동. 단, gz에 대하여 gzip 압축 추가 함 
// zip 압축하기 
$ git archive --format=zip --prefix=mqtt_java_client/ HEAD > mqtt_java.zip

// 확인
$ ls
README.md                   jmqtt_client-1.0.jar  mqtt_java.zip  src
eclipse_feature.properties  license.properties    pom.xml

// tar 압축하기 
$ git archive --format=tar --prefix=mqtt_java_client/ HEAD > mqtt_java.tar.gz

$ ls
README.md                   jmqtt_client-1.0.jar  mqtt_java.tar.gz  src
eclipse_feature.properties  license.properties    pom.xml


* 참조 : Git 선화

'Git, GitHub > Git Lec01' 카테고리의 다른 글

[Git] Release 브랜치 다루기  (0) 2012.12.20
[Git] tag 다루기  (0) 2012.12.20
[Git] Remote 저장소 연결 및 관리  (0) 2012.12.17
[Git] History 이용 및 관리하기  (0) 2012.12.13
[Git] Merge 종류와 충돌 해결하기  (0) 2012.12.12
posted by 윤영식