'분류 전체보기'에 해당되는 글 168건

  1. 2013.03.05 jQuery .HTML() 메서드 구현
  2. 2013.02.25 Hash List 모듈 사용 방법
  3. 2013.01.19 OctoberSkyJs 1차 스터디 후기 4
  4. 2012.12.24 Wire Shake를 통해 본 Keep-Alive 처리 과정 1
  5. 2012.12.18 웹 서버 상세 처리 과정
  6. 2012.12.13 HTTP Session 이란? 5
  7. 2012.11.20 [Node.js] For문과 비동기 Callback
  8. 2012.11.20 Node.js or Javascript Global Scope Test
  9. 2012.11.19 Node.js 비동기 이벤트 실행
  10. 2012.11.18 Node.js 실행스택(Execution Stack) 이벤트 처리 과정

jQuery .HTML() 메서드 구현




최근 작성 중인 JS에서 DB Call(Ajax)을 통해 받아온 데이터를 HTML과 함께 가공하여, 사용자로부터 전달된 특정 Element에 할당하는 로직을 구현해야 하는 일이 있었다.



해당 로직을 구현하기 위해 지금까지 DOM Manipulation(조작)을 위해 자주 사용해오던 속성인 innerHTML 속성을 사용해 구현하던 중 오랜만에 "멘붕"을 겪은 경험이 있어 아래와 같이 정리해보았다.





"멘붕"과 관련된 자세한 설명은 간단한 검색을 통해 많은 정보를 얻을 수 있으며, 아래 포스트를 참조하길 바란다.



1. tbody.innerHTML 안된다고?

http://findfun.tistory.com/entry/TIP-tbodyinnerHTML-%EC%9D%B4-%EC%95%88%EB%90%9C%EB%8B%A4%EA%B3%A0


2. Javascript Snippet - Tables and innerHTML

http://tech.pro/tutorial/1087/javascript-snippet-tables-and-innerhtml


3. DWR과 IE와 TBODY와 innerHTML과 협공

http://blog.iolo.kr/102





위 내용들을 간단히 정리하면, IE 브라우저타 브라우저(표준 브라우저(파폭, 사파리, 크롬))와 달리, 몇 가지 Element(Tbody, Table, HTML, COL 등)들의 메커니즘이 읽기 전용으로 되어있으며, 

그 엘리먼트들은 다른 엘리먼트와 달리 innerHTML 속성을 통해 사용자가 할당하려는 특정 HTMLString이 할당되지 않는다는 말이다.(하지만 jQuery.html(HTMLString) 메서드 사용 시 (IE / 비IE) 모두 완벽히 처리된다.)


하지만 현재 작성 중인 JS가 JQuery 라이브러리를 사용하지 않는 범위로 제작되고 있기에, 별도의 Html() 메서드를 따로 작성해야 했다.




아래는 별도로 작성된 Html() 메서드 소스이다.







Hash List 모듈 사용 방법



hlist.JS(Hash List) 적용 소스






1. 동작 원리




가장 먼저, 작성된 모듈의 기본이 되는 기능에 대해 설명하자면, 기존 URI의 #(해시) 기능인 앵커(anchor)를 응용한 기능이며, 보편적으로 아래와 같은 경우에 사용된다.




1.1 앵커 태그의 href 속성에 "#here" 문자열을 할당 시킨다.


1.2. 특정 태그(div)의 id 속성에 위 앵커 태그에 할당한 문자열을 동일하게 할당 시킨다.


1.3. 이와 같은 문서 환경이 구성되어 있는 경우, 해당 앵커의 기본 이벤트 발생 시 동일한 문자열로 할당된 특정 태그를 찾아 그 위치로 이동 시키는 기능을 사용할 수 있으며, 보통 사이트 가이드 문서의 목차 내용을 이동 시키는데 사용된다.




해당 기능은 아래 코드와 같이 구현된다.




<div id="here">there 영역!!</div>

<a href="#here">there 영역으로 가기!!!</a>



작성된 모듈(Hlist.js) 또한 데모 페이지에서 확인할 수 있듯이 위에서 설명한 #(해시) 기능을 응용한 방법이다.


- 제공되는 URI 형식이 아래와 같이 작성되는 이유는 기존 시멘틱한 URI 작성 방식을 최대한 손실시키지 않기 위함이다.



제공되는 URI 작성법:


http://mohwa.org/aspx/hlist/hlist.aspx?#list/page/5


: #(해시)list(proc)/page/5(parameters)








2. 적용에 따른 장 / 단점





장점: 


1. 페이지에 포함된 전체 리소스(정적 / 동적) 갱신없이(no reflash) 특정 영역의 데이터를 받아와 업데이트 하는 방식(+ajax)으로, 그에 따라 성능(네트웍 트래픽 감소, no reflash에 따른 페이지 로드 시간 감소 등..) 및 사용자 접근성이 향상 된다.



2. 방식 변경 후에도 사이트 기본 기능(북마크, 링크 공유, 검색엔진 인덱싱, 페이지 히스토리) 그대로 사용 가능하다.


즉 #(해시) 기능을 사용하는 가장 큰 이유는 전통적인 웹 사이트의 레가시(유산)를 깨뜨리지 않으려는 최소한의 절충한이라고 볼 수 있다.(HTML5 API의 pushState(Ajax History 관리) 기능은 아직까지 모든 브라우저에서 지원하지 않으므로(최신 표준 브라우저에서만 사용 가능) 기술 도입에 적당하지 않다.)



3. Cache 기능으로 정의된 CacheTimeout 안에는 DB Call을 하지않고 미리 적재된 캐쉬 데이터를 불러와 사용게 된다.






단점: 


1. 전체적으로 JS 기반인 기술이므로 JS 미 지원 브라우저에서는 동작하지 않는다



즉 그와 관련한 사용자 접근성 치명적인 단점이 존재한다. 


하지만 이를 대응하기 위한 방법이 존재하지 않는것은 아니다. 단, 개발 초입 시 이를 충분히 고려한 설계를 통해 미 지원 브라우저를 처리해야하며, 그에 따라 늘어나는 개발 비용은 충분히 고려해야할 부분이다.(기존 Form 태그의 Submit을 JS(form.submit())만을 이용한 설계(JS 미지원 브라우저에서는 동작하지 않는 설계)가 아닌 Submit(type="submit", type="image") 타입의 버튼 형식 및 Form 태그의 Onsubmit 이벤트를 통해 사용하는 방법을 떠올리면 이해가 빠를 듯 하다.)



또 다른 분기 처리 방법으로는 사이트 이원화를 생각해 볼 수 있다.

즉 JS 지원 여부에 따라 순수 HTML만으로도 동작하는 사이트로 리디렉션 해주는 방법이다.



2. JS 기반인 기술이므로 코드 상 작은 실수(JSON에서 콤마(,)를 찍지않는 작은 실수)로 인해 전체 웹 사이트가 망가질 리스크가 적지 않다.



3. 각종 "검색엔진"이 해당 사이트의 내용을 알기 위해 컨텐츠를 긁어가는 봇인 "크롤러"는 JS를 실행시키지 않으므로 #(해시) 기능으로 생성되는 사이트의 컨텐츠를 가져갈 수 없다.(비동기(ajax)를 사용한 컨텐츠 업데이트를 사용할 수 없기 때문)


즉 크롤러가 수집하는 페이지는 내용 없는 빈 페이지라는 얘기이다.







3. 적용 예제











4.  관련 사이트:



메뉴얼:

http://mohwa.org/doc/hlist/index.html


소스 페이지:

http://mohwa.org/aspx/hlist/hlist.js


데모 페이지(루리웹 페이지를 이용한 예제이며, 현재 페이징 기능 까지 구현되어 있다.)

http://mohwa.org/aspx/hlist/hlist.aspx?#list


URI(텀즈):

http://www.terms.co.kr/URI.htm


URL과 URI의 의미와 차이점: 

https://lael.be/480



OctoberSkyJs 1차 스터디 후기



OctoberSkyJs 1차 스터디 후기





올해 들어 나름 야심 차게 시작하고 전부터 큰 관심 가졌던 Node.JS 스터디 모임인 "OctoberSkyJs 1차 스터디 후기"를 간단히 제 블로그를 통해 남겨봅니다.


오늘은 개인적인 사정으로 인해 당일 발표 중 첫 번째, 두 번째 발표인 "Buffer"와 "C/C++ Addons"는 아쉽게도 들을 수 없었지만(특히 C/C++ Addons는 꼭 듣고 싶었던 발표이기에 더 큰 아쉬움이 남습니다.;;),


차후 "Groups Mail"을 통해 공개될 "발표 자료"를 기대해 봅니다. plz


그럼 후기의 본론인 스터디 얘기를 하자면, 오늘 제가 들은 발표는 총 2개의 발표였으며, 그 중 세 번째 주제였던 @백정상의 "Cluster"와 당일 발표자분의 부재로 인해 그 자리를 대신 메꿔 주셨던(소위 땜빵 발표?) @채수원님"libuv"에 대한 얘기였습니다.


특히 세 번째 발표인 "Cluster"란 주제는 스터디 예습을 전혀 하지 못한 제겐 시작부터 큰 "멘붕"을 느끼게 했고, 기반 지식(OS, 하드웨어, 엔진(V8)) 또한 그리 깊지 않아 발표 내내 최대한 이해하기 위해 노력했던 시간이었던 거 같습니다.(다행히도 다른 분들의 여러 질문이 이해하는 데 도움이 많이 되었답니다.ㅋㅋ) 


스터디 내용 중 생각나는 내용에 대한 주제를 간단히 적어보자면 Cluster란?적용 시 성능 향상은?(약 20 ~ 40%?)Child-Process 와의 관계? 등의 이야기였고 물론 100% 이해하기 힘들고 제겐 어려운 내용이었지만 성능 향상에 대한 새로운 부분을 알게 되어 아주 유익한 시간이었습니다.


또한 "땜방 발표"를 해주셨던 @채수원님의 "Libuv" 또한 Clouster의 내용과 같이 기반 지식이 부족한 현재로선 100% 이해하기 힘든 내용이었지만 역시 의미 있는 시간이었습니다.


그리고 발표하셨던 내용 중 어느 "한 부분"이 제겐 인상 깊게 남아 아랫글로 옮겨 봅니다.


"Node.JS는 JVM과는 달리 OS와 Machine 간에 최적화 레이어가 존재하지 않는다.(뒤에 따라오는 말은 그에 대한 성능과 관련된 말씀이셨는데 정확히 생각나지 않고 이해 또한 잘 되지 않아 이 글에 옮겨 적지 않겠습니다.(괜찮으시다면 댓글로 직접 남겨 주셔도 좋을 듯합니다.^^;;))



그럼 후기의 끝으로 앞으로 남은 "스터디" 현재 모든 맴버들과 같이 잘 마무리 할 수 있기를 빌며...


1차 후기를 마칩니다.!!




Wire Shake를 통해 본 Keep-Alive 처리 과정

 



Wire Shake를 통해 본 Keep-Alive 처리 과정







1. HTTP 기본 구조(HTTP 1.0 이하)




파란 테두리: 첫 번째 Socket(TCP) 연결 및  HTTP Request/Response 처리 과정

빨간 테두리: 두 번째 Socket(TCP) 연결 및  HTTP Request/Response 처리 과정



위 그림(Wire Shake 예제)에서와 같이 HTTP는 기본적으로 Connection-Less 방식을 가진다. 즉 맷어진 Socket 연결은 유지되지 않고 매번 끊어지며다시 생성 되는 구조이다.



웹 서버 상세 처리 과정:

http://mohwaproject.tistory.com/entry/%EC%A0%95%EC%A0%81%EB%8F%99%EC%A0%81-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%9B%B9-%EC%84%9C%EB%B2%84-%EC%B2%98%EB%A6%AC-%EA%B3%BC%EC%A0%95







2. Keep-Alive(HTTP 1.1 이상) 기능 이란?


위 HTTP 기본 구조를 바탕으로 맷어진 Socket 연결이 종료된 시점(HTTP Response 이후)부터 웹 서버에 정의된 Keep-Alive Timeout 까지 기존 연결(Socket)유지하는 기능.


즉, 정의된 시간(Keep-Alive Timeout) 내에 새로운 HTTP 요청이 발생한다면? 맷어진 Socket 연결을 지속적으로 유지할 수 있다.(앞서 말한바와 같이 지속적인 연결은 유지되나 정의된 Keep-Alive Timeout  시간은 정확히 지켜지지 않는다.(보통 정의된 시간보다 Socket 연결일찍 끊어진다.)



IIS 테스트 결과 정의된 시간의 50% 이상 일찍 끊어진다.(120초 / 2)







3. IIS(6 / 7) Keep-Alive 설정 방법



- IIS 6


1. Keep-Alive 활성화 설정 및 Keep-Alive Timeout 정의


- 연결 시간 제한은 기본 120초를 갖는다.






- IIS 7:


1. Keep-Alive 활성화 설정












2. Keep-Alive Timeout 정의


연결 시간 제한은 기본 120초를 갖는다.












4. 웹 서버 HTTP Connection 변화




- Keep-Alive 비활성화 시:


1. 아래 예제와 같이 맷어진 HTTP Connection(Socket 연결)은 유지되지 않고 바로 끊어진다.(Current Connection 0.000)


2. Response-Header Field인 Connection 값으로 "close" 를 응답한다.








- Keep-Alive 활성화 시:


1. 아래 예제에서와 같이 맷어진 HTTP Connection(Socket 연결)은 유지된다.(Current Connection 1.000)


지속적인 연결은 유지되나 정의된 Keep-Alive Timeout(120초)  시간은 정확히 지켜지지 않는다.(보통 정의된 시간보다 Socket 연결이 일찍 끊어진다)


2. Response-Header Field인 Connection 필드는 존재하지 않는다.(IIS 기준)










5.  Wire Shake를 통해 본 Keep-Alive 처리 과정



파란 테두리: 첫 번째 Socket(TCP) 연결 및  HTTP Request/Response 처리 과정

빨간 테두리: 두 번째 Socket(TCP) 연결 및  HTTP Request/Response 처리 과정(Keep-Alive 활성화 시 HTTP 기본 구조와 달리 TCP 세션 수립과정 중 일부가 생략 되었다는걸 볼 수 있다.)







Keep-Alive 처리 과정


1. HTTP Session(논리적 연결) 생성




2. 정의된 Keep-Alive Timeout 내에 새로운 HTTP 요청이 발생할 경우, 새로운 Socket을 재 생성하는 것이 아닌 활성화 된 Keep-Alive 기능을 통해 유지된 Socket 연결 Request하게 된다.


즉, Socket 연결에 필요한 모든 비용이 감소하게 되며, 그에 따라 전체적인 성능도 좋아지게 된다.




3. 클라이언트(브라우저)와 웹 서버는 HTTP Request 및 Response를 수행한다.




4. 정의된 Keep-Alive Timeout 동안 맷어진 Socket 연결은 지속적으로 유지된다.




5. HTTP Session Close


- 클라이언트(사용자) 접속 종료 시 서버에 적재된 HTTP Session은 소멸된다.






- Keep Alive Timeout(연결 유지 시간) 종료 시 처리 과정



파란 테두리: 첫 번째 Socket(TCP) 연결 및  HTTP Request/Response 처리 과정


빨간 테두리: 두 번째 Socket(TCP) 연결 및  HTTP Request/Response 처리 과정(Keep-Alive 활성화 시 HTTP 기본 구조와 달리 TCP 세션 수립과정 중 일부가 생략 되었다는걸 볼 수 있다.)


- 주황 테두리: Socket(TCP) 연결 및  HTTP Request/Response 처리 과정(정의된 Keep-Alive Timeout(연결 유지 시간) 종료  첫 번째 요청과 같이 TCP 세션 수립과정다시 발생하게 된다.)







TCP 세션 수립 과정

http://mohwaproject.tistory.com/entry/TCP-3-Way-HandshakeTCP-%EC%84%B8%EC%85%98-%EC%88%98%EB%A6%BD


HTTP 1.1 Keep-Alive 기능에 대해

http://pungjoo.tistory.com/2


웹 서버 상세 처리 과정






1. 정적 페이지 접근 시(HTTP Server)




- 브라우저를 통한 정적 페이지(html, img, js, css, xml등) 접근 시 웹 서버 내부 처리 과정은 아래와 같다.









- Wite Shark를 통해 본 TCP/HTTP 처리 과정



- 파란 테두리: Socket(TCP) 처리 과정을 나타낸다.(TCP 세션 수립)

- 빨간 테두리: HTTP Request/Response 처리 과정을 나타낸다.




1. HTTP Session(논리적 연결) 생성


2. 클라이언트(브라우저) 프로그램안의 ThreadClient Socket(TCP(임의의 남는 랜덤 포트))을 만들어(생성) 서버 Socket(TCP(80))에 연결을 수행한다.(이때 Client-Socket에는 HTTP 통신 전문(Request-Header ) 대한 내용이 포함된다.)


- 이 과정을 통해 TCP 세션 수립(3-way HandShaking)이 완료된다.

- 이 과정을 통해 Client/Server 메시지(데이터 패킷) 교환 준비가 완료된다.


3. "웹 서버"는 요청된 Client-Socket 데이터(HTTP 통신 전문)를 바탕으로 HTTP Request Response를 수행한다.


3. 클라이언트(브라우저)와 웹 서버는 HTTP Request 및 Response를 수행한다.


4. 서버 Socket Close(웹 서버는 HTTP Response 수행 후 생성된 서버 Socket을 닫는다. 하지만 Socket은 보통 바로 끊어지지 않고 얼마간 Listen(대기) 상태로 유지된다.)


5. 클라이언트 Socket Close 및 브라우저 쓰레드 종료.


6. HTTP Session Close

- 클라이언트(사용자) 접속 종료 시 서버에 적재된 HTTP Session은 소멸된다.






2. 동적 페이지 접근 시(HTTP Server + WAS 구성 시)




- 브라우저를 통한 동적 페이지(asp, aspx, php, jsp등) 접근 시 웹 서버 내부 처리 과정은 아래와 같다.





1. HTTP Session(논리적 연결) 생성


2. 클라이언트(브라우저) 프로그램안의 Thread가 Client Socket(TCP(임의의 남는 랜덤 포트))을 만들어(생성) 서버 Socket(TCP(80))에 연결을 수행한다.(이때 Client-Socket에는 HTTP 통신 전문(Request-Header ) 대한 내용이 포함된다.)


이 과정을 통해 TCP 세션 수립(3-way HandShaking)이 완료된다.

이 과정을 통해 Client/Server 메시지(데이터 패킷) 교환 준비가 완료된다.


3. "웹 서버"는 요청된 Client-Socket 데이터(HTTP 통신 전문)를 바탕으로 HTTP Request 및 Response를 수행한다.


3. 클라이언트(브라우저)와 웹 서버는 HTTP Request 및 Response를 수행한다.


- 이때 요청된 동적 페이지(index.aspx) 처리를 위해 WAS에 요청(구문 해석) 후 그 결과(*.html)를 응답한다.


4. 서버 Socket Close(웹 서버는 HTTP Response 수행 후 생성된 서버 Socket을 닫는다. 하지만 Socket은 보통 바로 끊어지지 않고 얼마간 Listen(대기) 상태로 유지된다.)


5. 클라이언트 Socket Close 및 브라우저 쓰레드 종료.


6. HTTP Session Close

- 클라이언트(사용자) 접속 종료 시 서버에 적재된 HTTP Session은 소멸된다.



IIS는 웹 서버(정적 컨텐츠 처리) +  WAS(보통 동적 컨텐츠 처리를 위해 사용)가 결합된 형태를 가진다즉, 분리된(웹 서버 + WAS) 형태와는 달리 내부 처리 과정이 다소 상이 할 수 있다. 하지만 기본 계념은 크게 벗어나지 않는다.


웹 서버의 주된 역활은 클라이언트/서버간의 HTTP 통신이며, WAS 비지니스 로직처리가 포함된 동적 페이지 처리   비중을 둔다.(정적 페이지 처리 또한 가능하다.)






3. HTTP Session Close 처리



- 클라이언트 접속 종료  서버에 적재된 HTTP Session은 소멸된다.(이 과정을 통해 브라우저에 생성된 Memory Cookie도 같이 소멸된다.)




1. 사용자 물리적 접속 종료 이벤트(브라우저 닫기 )


2. HTTP Session Timeout


- HTTP Session 생성 후 웹 서버에 접근한 클라이언트(사용자)가 서버에 할당된 Session Timeout 시간 까지 아무런 사용자 이벤트(사이트 내부에서 일어나는 모든 행위)를 발생 시키는 않을 경우 웹 서버는 내부적으로 논리적 세션 연결을 끊어버린다.)


3. 웹 서버 재 시작(IIS Restart)


4. *.dll 파일 Re-Build 과정(ASP.NET 기준) 






참고 사이트:


web server와 WAS(web application server)

http://pds5.egloos.com/pds/200708/18/42/200703_WAS(Web_Application_Server).pdf


TCP 세션 수립 과정

http://mohwaproject.tistory.com/entry/TCP-3-Way-HandshakeTCP-%EC%84%B8%EC%85%98-%EC%88%98%EB%A6%BD



HTTP Session 이란?



1. HTTP Session이란?









1. session이란? 서버가 해당 서버(웹)로 접근(request)클라이언트(사용자)를 식별하는 방법


2. 서버(웹)는 접근한 클라이언트(사용자)에게 response-header field인 set-cookie 값으로 클라이언트 식별자인 session-id(임의의 긴 문자열)를 발행(응답)한다.


3. 서버로부터 발행(응답)된 session-id는 해당 서버(웹)와 클라이언트(브라우저) 메모리에 저장된다. 

이때 클라이언트 메모리에 사용되는 cookie 타입은 세션 종료 시 같이 소멸되는 "Memory cookie"가 사용된다.


4. 서버로부터 발행된 session(데이터)을 통해 개인화(사용자)를 위한 데이터(userInfo 등..)로 활용할 수 있다.





2. HTTP Session 동작 순서



1. 클라이언트(사용자)가 서버로 접속(http 요청)을 시도한다.


2. 서버(웹)는 접근한 클라이언트의 request-header field인 cookie를 확인해 클라이언트가 해당 session-id를 보내왔는지 확인한다.


3. 만약 클라이언트로 부터 발송된 session-id가 없다면, 서버는 session-id를 생성해 클라이언트에게 response-header field인 set-cookie 값으로 session-id(임의의 긴 문자열)를 발행(응답)한다.




* 첫 번째 요청(http) 시 클라이언트로 부터 발송된 session-id 가 없으므로 서버는 session-id를 생성해 클라이언트에게 발행(응답)한다.






* 두 번째 요청(http) 시 클라이언트는 서버로 부터 발행(응답)된 session-id를 request-header cookie 값으로 포함하고 있다.





4. 서버로부터 발행(응답)된 session-id는 해당 서버(웹)와 클라이언트(사용자 브라우저) 메모리에 저장된다. 


이때 사용되는 cookie 타입은 세션 종료 시 같이 소멸되는 "memory cookie"가 사용된다.



5. 클라이언트 접속 종료(브라우저 닫기 등..) 시 서버에 저장된 session-id(server resource 소유)는 소멸된다.





3. 각 브라우저 별 Session Life Circle




1. IE(8 기준):



1.1 클라이언트가 첫 번째 요청을 시도한다.





1.2 새로운 탭을 활성화 시킨 후 재 요청을 시도한다.(첫 번째 요청 session-id 값과 동일)





1.3 새로운 창을 활성화 시킨 후 재 요청을 시도한다.


- 아래 그림과 같이 IE(8 기준) 브라우저의 경우 신규 창 활성화 후 재 요청 시 session-id가 변경된 것을 볼 수 있다.(즉, 신규 탭과 달리 신규 창의 경우 서버로 부터 새로운 session(id)을 발급받게 되는 것이다..)










2. Chrome(버전 23.0.1271.97 m)



2.1 클라이언트가 첫 번째 요청을 시도한다.


- Chrome 브라우저와 같은 경우 첫 번째 요청 시 다른 브라우저들의 결과와 달리 response-headerset-cookie값이 아닌 두 번째 요청의 결과와 같은 request-header의 cookie 값으로 session-id가 포함되어있다.







2.2 새로운 탭을 활성화 시킨 후 재 요청을 시도한다.(첫 번째 요청 session-id 값과 동일)





2.3 새로운 창을 활성화 시킨 후 재 요청을 시도한다.


IE(8 기준) 브라우저와 달리 신규 창 활성화 후 재요청 시에도 기존 session-id는 변하지 않는다.






3. Firefox(버전 17.0.1)




3.1 클라이언트가 첫 번째 요청을 시도한다.






3.2 새로운 탭을 활성화 시킨 후 재 요청을 시도한다.(첫 번째 요청 session-id 값과 동일)






3.3 새로운 창을 활성화 시킨 후 재 요청을 시도한다.



신규 창 활성화 후 재요청 시에도 기존 session-id는 변하지 않는다.








4. Safari(버전 5.01)




4.1 클라이언트가 첫 번째 요청을 시도한다.






4.2 새로운 탭을 활성화 시킨 후 재 요청을 시도한다.(첫 번째 요청 session-id 값과 동일)


- Safari 브라우저의 경우 이전 브라우저들의 결과와 달리 request-header cookie값으로 session-id가 포함 되지 않는다.






4.3 새로운 창을 활성화 시킨 후 재 요청을 시도한다.



신규 창 활성화 후 재요청 시에도 기존 session-id는 변하지 않는다.










참고 사이트: 


http session(위키):

http://en.wikipedia.org/wiki/Session_(computer_science)


http session에 대해서 알아보자:

http://tobewiseys.tistory.com/72


http session hijacking:

http://www.iamcorean.net/145


Cookie, Session 이란:

http://www.lovelgw.com/Blog/243



[Node.js] For문과 비동기 Callback




"JS 비동기 이벤트 실행 순서"로 인해 첫 번째 예제의 타이머 이벤트 callback은 for 문이 종료된 후 실행된다.


즉, 이벤트 큐에 쌓인(Event Loop 감지 후) 이벤트 callback들의 실행 시점은 for문 에서 선언된 i 변수가 증감 후 9가 되어 루프를 빠져나온 시점인 것이다.





1. Client-Side 코드 예제



for (var i = 0; i < 10; i++){
	
	this.setTimeout(function(){
		
		console.log(i); // 10
		
	}, 10);
}

// 아래 나머지 예제들은 문법 상 차이만 존재하며, 의미는 동일하다.
// 즉, 타이머 이벤트나 전달되는 callback에 즉시 실행 함수를 랩핑하여 클로저를 발생시켜 위 문제를 해결한다.

for (var i = 0; i < 10; i++){
	
	// 타이머 이벤트에 즉시 실행 함수를 랩핑.
	(function(i){
		this.setTimeout(function(){
			
			console.log(i); // 0 ~ 9
			
		}, 10);
	})(i);
}	

for (var i = 0; i < 10; i++){
	
	// 전달되는 타이머 이벤트의 callback에 즉시 실행 함수를 랩핑.
	this.setTimeout((function(i){
		
		return function(){
			console.log(i); // 0 ~ 9
		}
		
	})(i), 10);
}	






2. Server-Side Node.js 코드 예제


- Server-Side Javascript인 Node.js도 위 동작 방식과 동일하다.



for (var i = 0; i < 10; i++){
	
	// setTimeout 타이머와 같이 비동기로 동작한다
	process.nextTick(function(){
		
		console.log(i); // 10
		
	});
}

for (var i = 0; i < 10; i++){
	
	// 타이머 이벤트에 즉시 실행 함수를 랩핑.
	(function(i){
		process.nextTick(function(){
			
			console.log(i); // 0 ~ 9
			
		});
	})(i);
}	

for (var i = 0; i < 10; i++){
	
	global.setTimeout((function(i){
		
		return function(){
			console.log(i); // 0 ~ 9
		}
		
	})(i), 10);
}	




3.결과




Node.js or Javascript Global Scope Test





1. Client-Side Javascript 전역 객체



// 명시적 전역 변수 선언
var global1 = 'global1';

(function(){
	
	// 암묵적 변수 선언(안티패턴)
	global2 = 'global2';
	this.global3 = 'global3'; 
})();


console.log(typeof window.window.global1); // string
console.log(typeof window.window.global2); // string
console.log(typeof window.window.global3); // string

// delete 연산자로 window 객체의 property 삭제
delete window.window.global1;
delete window.window.global2;
delete window.window.global3;

console.log('');

// 명시적으로 선언된 global1 전역 변수는 엄밀히 말해 아래 결과와 같이 delete 연산자로 객체가 소멸되지 않는다.
// 즉, 객체 속성 및 배열의 요소를 제거하는 delete 연산자로 삭제가 되지 않기 때문에 엄밀히 말해 window 객체의 속성으로 볼 수 없다.
console.log(typeof window.window.global1); // string
console.log(typeof window.window.global2); // undefined
console.log(typeof window.window.global3); // undefined



자바스크립트 변수

http://mohwaproject.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8A%A4%EC%BD%94%ED%94%84-%EA%B4%80%EB%A6%AC-1


자바스크립트 함수 유효범위(Scope)란?

http://mohwaproject.tistory.com/entry/%ED%95%A8%EC%88%98%EC%9D%98-%EC%9C%A0%ED%9A%A8%EB%B2%94%EC%9C%84SCOPE%EB%9E%80






2. Server Side Javascript Node.js 전역 객체




2.1 확장 모듈 helloworldExFn.js 코드


module.exports.helloworldExFn = (function(){
	
	var helloworldEx = function(){
		
		this.id = 'mohwa';
		this.name = 'mohwaName';
		
		return this;
	}
	
	// 전역 속성 선언 및 할당
	global.g_createValue1 = 'g_createValue1';
	this['g_createValue2'] = 'g_createValue2';
	
	return helloworldEx;
	
})();



2.2 호출 페이지 코드


// Node 전역 객체의 Console.log 함수 반환
console.log('1. ' + global.console.log);

// Node 전역 객체의 생성자 함수 반환
console.log('2. ' + global.constructor);

// 빈 전역 객체 반환
console.log('3. ' + this);


// Node.js에서는 Client-Side JS와 달리 함수 밖 "this"는 전역 객체인 global을 가리키지 않는다.

// 빈 전역 객체 생성자 함수 반환
console.log('4. ' + this.constructor);


(function(){
	
	// Node 전역 객체의 Console.log 함수 반환(Client-Side JS와 같이 함수 객체 내부에서는 빈 전역 객체가 아닌 Node 전역 객체 "global"을 반환한다.)
	console.log('5. ' + this.console.log);
	
})();


// 확장 모듈 내부에 전역 변수 생성.

// require(객체) 메서드는 외부 리소스로 제공된 확장 모듈을 가져와 반환({} 타입)한다.
// 그리고 제공된 확장 모듈안 helloworldExFn 맴버는 반환되는 객체의 맴버로 정의된다.

var obj = new require('./helloworldEx.js').helloworldExFn();

// new helloworldExFn() 객체의 id 속성 반환
console.log('6. ' + obj.id);
// new helloworldExFn() 객체의 name 속성 반환
console.log('7. ' + obj.name);


var g_createValue1 = 'g_createValue1';

// 명시적 전역 변수는 g_createValue1를 제거한다.
// 하지만 Client-Side JS와 동일하게 명시적 전역변수는 delete 연산자를 통해 제거되지 않는다.
delete g_createValue1;

// 확장 모듈 내부에서 선언된 암묵적 전역 변수인 g_createValue2를 제거한다.
delete g_createValue2;

// 확장 모듈 내부에서 선언된 암묵적 전역 변수인 g_createValue3를 제거한다.
delete g_createValue3;

console.log('8. ' + typeof g_createValue1);
console.log('9. ' + typeof g_createValue2);
console.log('10. ' + typeof global['g_createValue3']);





3. 결과:




이전 포스트에서 "Node.js 아키텍처 방식"에 대해 간단히 설명한 적이 있다. 


즉, "Node 아키텍처 최 상단 레이어"인 "Node Standard LIbrary"를 통해 기존 Client-Side Javascript 문법이 활용 가능하며, 전체 적인 동작 방식(전역객체, 유효범위 등..)또한, 기존 JS와 많은 부분 흡사하다는 것을 알 수 있다.




Node.js 비동기 이벤트 실행





1. Node.js 비동기 실행 테스트


(function(){
	
	var args = arguments;


	// 첫 번째 비동기 요청
	this.setTimeout(function(){
		
		console.log('1 Async Start=' + new Date().getTime());
		
		// 첫 번째 동기 CallBack(다음 비동기 요청을 지연(대기)시킨다.)
		for (var i = 0; i < 10; i++){
			
			console.log('1 Async Time=' + new Date().getTime());
		}
		
	}, 1001);

	// 두 번째 비동기 요청
	this.setTimeout(function(){
		
		console.log('2 Async Start=' + new Date().getTime());
		
		// 두 번째 비동기 CallBack
		setTimeout(function(){
			
			for (var i = 0; i < 10; i++){
				
				console.log('2 Async Time=' + new Date().getTime());
			}
			
		}, 10);		
	}, 1000);
	
	
	// 세 번째 비동기 요청
	this.setTimeout(function(){
		
		console.log('3 Async Start=' + new Date().getTime());
		
		// 세 번째 비동기 CallBack
		setTimeout(function(){
			
			for (var i = 0; i < 10; i++){
				
				console.log('3 Async Time=' + new Date().getTime());
			}	
			
		}, 10);		
	}, 1000);	
	
})();



2. 결과




1. (두, 세)번째 비동기 요청이 "요청 실행 시점"(1초)에 맞게 먼저 실행된다.(1353241683913, 1353241683915)


2. 첫 번째 비동기 요청이 실행된다.(1353241683915)


3. 첫 번째 요청에 대한 동기 CallBack이 실행된다.(Javascript Code Block(1353241683916))


4. "비동기 이벤트 실행 순서"에 따라 첫 번째 CallBack의 "동기식 Javascript Code Block" 실행 완료 (두, 세)번째 CallBack이 동시 진행 됐다.(1353241683925)


5. (두, 세) 번째 CallBack이 동시 실행 후 완료된다.(1353241683925)





Node.js 비동기 처리의 환상

http://seorenn.blogspot.kr/2011/05/nodejs_26.html


Javascript Single Thread

http://mohwaproject.tistory.com/entry/javascript-single-thead


Node.js 실행스택(Execution Stack) 이벤트 처리 과정




1. Node.js 아키텍처 및 프로세스 모델








1. Node.js는 크게 Javascript 언어 레이어(C, C++) 언어 레이어로 나뉜다.


2.   C++로 작성된 구글의 Javascript 엔진인 "V8"과 이벤트 기반 Non-Blocking I/O(비동기 I/O)를 관리하는 "libero(Thread Poll 담당)"와 이벤트 루프를 담당하는 "libev"가 아키텍처 최하단에 위치한다.


3.  그 위에 Socket 및 Http등에 대한 "node bindings" 레이어(노드에서 작성된 API(C++))는 "Node Standard Library"의 인터페이스 역활을 한다.(Node 저장소에 있는 소스 중 src/*.cc 에 포함되어 있고 Node Standard Library 대부분이 래퍼들과 동작하게 된다.)


4. Node Standard Library 레이어는 Node Bindings 레이어에서 제공되는 Node API(C++)시스템상에서 Javascript 문법을 이용해 I/O 프로그래밍을 할 수 있도록 지원하는 Server Side 라이브러리이다.











2. Node.js 웹 서버 구현 코드:



var server = require('http');

var fs = require('fs');
var url = require('url');

var reqUrl = '';

server.createServer(function(req, res){
	
	fs.readFile('./nodeHtml.html', encoding='utf-8', function(err, data){
		
		if (err){
			throw err;
		}
		else{
			
			res.write(data);
			res.end();
		}
	});
	
}).listen(3000);






3. 실행 스택(Execution Stack) 이벤트 처리 과정



1. 노드는 Single Thread를 사용하므로, 실행 스택(Execution Stack)도 하나만 존재한다.(Stack을 통해 Event Loop가 처리된다.)


2. 한번에 하나의 이벤트(Node API에 포함된 각 이벤트)와 관련된 Stack만 추가된다.


즉, Event Loop를 통한 서로 간의 간섭(Dead Lock(리소스 병목현상))은 일어나지 않는다.(한번에 하나의 이벤트만 추가되기 때문에..) 


"실행 스택 " 최하단 에는 Event Loop를 처리하는 ev_loop()가 존재하며, 계속 실행되고 있다가 이벤트 발생하면 감지 후 필요한 Stack을 실행 스택에 추가시킨다.





3.1 "실행스택" 이 추가되는 이벤트를 처리하는 과정



1. 첫 번째 사용자가 웹 서버(Node.js로 구현된..)에 index.html을 요청한다.


2. 이벤트 루프(Event Loop)는 이를 감지 후 요청 소켓을 읽기 위해 "scket_readble Stack"을 추가한다.(현재 Stack: 1개)


3. HTTP 요청을 해석하는 "http_parse Stack"을 추가 하고(현재 Stack: 2개) index.html 파일에 대한 요청이므로 "load('index.html') Stack"을 추가하고(현재 Stack: 3개) index.html 파일 읽기를 요청한다.



4. index.html을 읽어 들이는 I/O를 요청했으므로 그로 인해 추가된 Stack 3개(scket_readble Stack, http_parse Stack, load('index.html') Stack)를 추가한 순서대로 제거해 나간다.(모두 제거되면 실행스택은 이벤트 루프만 돌고 있는 대기 상태에 있게 된다.)



*** 아직까지는 첫 번째 사용자가 요청한 index.html의 응답을 보내기 위해 파일 I/O를 요청만 완료된 상태이며, 응답을 기다리는 중이다.!!!! ***



5. 이 상태(상황)에서 메모리상에 존재하는 두번째 사용자의 index.html 요청이 들어온다.


6. 두 번째 요청 또한, 첫 사용자와 동일한 과정을 거쳐 실행 스택에 해당 Stack(각 이벤트에 대한 Stack 3개)들을 추가 시켜 나간다.


7. "두 번쨰 요청을 처리하는 중!!" 첫 번째 사용자 요청인 index.html 파일을 읽는 I/O 처리가 완료되었다.!!!!



"해당 이벤트가 발생했지만 현재 두 번째 "요청에 대한 Stack이 존재"하므로 바로 처리되지 않고 이벤트를 대기 시킨다.



설명: 

Non-Blocking I/O 방식은 요청 이벤트를 blocking 하지 않는다.

즉, 두 번째 요청에 대한 Stack이 모두 제거(추가된 순서대로...)돼야 이벤트 루프는 다음 이벤트를 처리해 나간다.



8. 대기 중이던 첫 번째 사용자 요청에 대한 응답(로드된 index.html 파일 읽기 이벤트)을 처리하기 위해 "file_loaded() Stack"을 추가(현재 Stack: 1개)해 I/O가 돌려준 index.html 파일을 받는다.


9. 첫 번째 요청에 응답하기 위해 "http_respond Stack"을 추가 후(현재 Stack: 2) 사용자에게 받은 index.html 파일로 응답을 생성해 사용자에게 응답을 보낸다.



10. 응답이 완료됐으며, 그에 따라 첫 번째 사용자의 응답을 위해 추가된 모든 Stack은 모두 순차적(추가된 순서)으로 제거된다.



11. 두 번째 사용자 또한 이 과정을 통해 해당 사용자 응답을 보낸 후 스택에서 제거된다.



단 비동기 방식(이벤트 방식)은 응답에 대한 순서를 보장하지 않는다

즉, 요청은 순차적으로 이루어지나, 그에 대한 응답은 순서를 보장하지 않는다는 뜻이다.








C++  Addon With Node.js

http://rhio.tistory.com/365


Node.js Ebay

http://www.slideshare.net/rheehot/nodejs-review


Node JS 프로그래밍(책)

http://www.yes24.com/24/goods/6271069



prev 1 2 3 4 5 6 ··· 17 next