HTTP 서버 생성

HTTP 서버를 생성할 때는 각 HTTP 요청을 어떻게 처리해야 하는지 정의한 콜백 역할을 하는 익명함수가 createServer에 이자로 전달됩니다. 콜백 함수는 request 와 response 두개의 인자를 받습니다. 콜백이 실행될 때 HTTP 서버는 두개의 인자로 사용될 객체를 생성해 전달하게 되는데 이를 이용해 세부적인 요청사항에 대한 처리와 응답을 보내게 됩니다. server.js 파일에 아래의 코드를 추가해 줍니다.

 server.js

1
2
3
4
5
6
7
8
9
10
var server = http.createServer(function(request, response) {
  var filePath = false;
  if(request.url == '/') {
    filePath = 'public/index.html';
  } else {
    filePath = 'public' + request.url;
  }
  var absPath = './' + filePath;
  serveStatic(response, cache, absPath);
});
cs

 

▷HTTP 서버 시작

지금까지 HTTP 서버를 생성하는 코드를 작성했지만, 아직 서버를 구동하는데 필요한 로직을 추가하지 않았습니다. TCP/IP 3000번 포트로 요청받는 서버를 구동할 수 있게 로직을 추가해보겠습니다. 3000번 포트는 임의로 선택한 숫자입니다. 1024보다 큰 숫자중에서 사용되지 않는 번호를 선택해 포트로 사용할 수 있습니다.  server.js 파일에 다음의 코드를 추가해보겠습니다.

 server.js

1
2
3
server.listen(3000, function() {
  console.log("Server listening on port 3000.");
});
cs

 

이제 어플리케이션이 어떻게 동작하는지 보기 위해 다음 명령을 명령행 프롬프트(CMD)에 입력해 서버를 구동해보겠습니다.

먼저 CMD창을 열어줍니다. (윈도우키 + R 을 눌러 실행창에 cmd라고 입력 or 윈도우키를 누르고 명령 프롬프트 찾기) 

그리고 프로젝트 폴더로 이동한뒤에 node server.js 라고 입력해줍니다.

 

그럼 서버가 시작되었을텐데요 이 상태에서 웹 브라우저에서 'http://127.0.0.1:3000 ' or 'http://localhost:3000' 에 방문하면 404 오류 함수가 실행돼 "Error 404 : resource not found" 라는 메시지가 출력될 것입니다. 정적 파일을 처리하는 로직을 추가했지만, 아직 정적 파일을 추가하지 않았기 때문입니다. 실행 중인 서버는 Ctrl-C 를 눌러 중단할 수 있습니다.

 

 

▷HTML, CSS 파일 추가

이제 가장 먼저 추가할 정적 파일은 기본 HTML파일 입니다. public 디렉토리에 index.html 파일을 생성하고 코드를 작성하겠습니다.

HTML은 CSS 파일을 가져오고 어플리케이션 내용을 표시할 HTML div 요소를 만들며, 여러 개의 클라이언트 측 자바스크립트 파일을 불러옵니다.

불러온 자바스크립트 파일은 클라이언트 측의 Socket.IO 기능, 쉬운 DOM 조작을 위한 jQuery, 어플리케이션에 적합한 채팅 기능을 제공하기 위한 파일입니다.

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Chat</title>
    <link rel='stylesheet' href="stylesheets/style.css"></link>
  </head>
  <body>
    <div id='content'>
      <div id='room'></div>
      <div id="room-list"></div>
      <div id="messages"></div>
 
      <form action="" id="send-form">
        <input type="text" id="send-message"/>
        <input type="submit" id="send-button" value="Send"/>
        <div id="help">
          Chat commands:
          <ul>
            <li>Change nickname:<code>/nick [username]</code></li>
            <li>Join/create room:<code>join [room name]</code></li>
          </ul>
        </div>
      </form>
    </div>
    <script src="/socket.io/socket.io.js" type="text/javascript"></script>
    <script src="http://code.jquery.com/jquery-1.8.0.min.js" type="text/javascript"></script>
    <script src="/javascripts/caht.js" type="text/javascript'/"></script>
    <script src="javascripts/chat_ui.js" type="text/javascript"></script>
  </body>
</html>
cs

 

10행 : 현재 채팅방 이름을 표시할 div

11행 : 참여할 수 있는 채팅방 목록을 표시할 div

12행 : 채팅 메시지를 표시할 div

15행 : 사용자가 명령어와 메시지를 입력하라 Form 구성요소

 

 

다음으로 추가할 파일은 어플리케이션의 CSS 스타일을 정의한 파일입니다. public/stylesheets 디렉토리에 style.css 파일을 만들어줍니다.

style.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
}
{
  color: #00B7FF;
}
#content {
  width: 800px;
  margin-left: auto;
  margin-right: auto;
}
#room {
  background-color: #ddd;
  margin-bottom: 1em;
}
#messages {
  width: 690px;
  height: 300px;
  overflow: auto;
  background-color: #eee;
  margin-bottom: 1em;
  margin-right: 10px;
}
 
cs

 

10행 : 어플리케이션은 800픽셀 너비에 가로로 중앙 정렬

15행 : 현재 참여하고 있는 채팅방 이름을 표시하는 영역의 CSS

19행 : 메시지 표시 영역은 가로 690픽셀, 세로 300픽셀 크기로 지정

 

HTML과 CSS작성이 완료되면 어플리케이션을 실행해 웹 브라우저에서 확인해봅니다. 

 

 

어플리케이션의 기능은 아직 구현되지 않았지만, 정적 파일이 서비스되고 기본적인 외형을 갖췄습니다. 이제 서버측에서 채팅 메시지를 전달하는 부분을 만들어 보겠습니다.

 

▷Socket.IO를 이용한 채팅 관련 메시지 처리방법

1부에서 말했던 필수기능 3가지 중 첫번재 항목인 정적 파일 서비스를 완료했습니다. 이제 두번째 항목인 브라우저와 서버 간 통신을 시작할 차례입니다.

최신 브라우저는 웹소켓을 사용해 브라우저와 서버 사이의 통신을 처리합니다.

Socket.IO는 노드와 클라이언트 측 자바스크립트 모두에서 사용하는 웹소켓과 그 외 다른 전송 방식을 위한 추상화된 계층을 제공합니다. Socket.IO는 웹소켓이 브라우저에 구현돼 있지 않더라도 같은 API를 사용할 수 있도록 적절한 전송 방식으로 대체합니다.

▶ Socket.IO가 제공하는 가상 채널을 이용하면 접속한 모든 사용자에게 메시지를 뿌리지 않고 특정 채널을 구독하는 사용자에게만 메시지를 전송할 수 있습니다. 이 기능을 이용하면 채팅 어플리케이션의 채팅방 기능을 매우 간단하게 구현할 수 있습니다.

그리고 Socket.IO는 이벤트 발생자의 유용함을 보여주는 좋은 예입니다. 이벤트 발생자는 원래 편리하게 비동기 롲기을 관리하기 위한 디자인 패턴입니다.

 

 

▷Socket.IO 서버 구성

다음 두 줄을 server.js 에 추가해줍니다. 첫번째 줄은 서버 측에서 Socket.IO 기반으로 대화 기능에 대한 로직을 제공하는 커스텀 모듈을 가져옵니다.

다음 줄은 Socket.IO 서버 기능을 시작합니다. 이미 정의한 HTTP 서버를 이용하므로 같은 TCP/IP 포트를 공유할 수 있습니다.

server.js

1
2
var chatServer = require('./lib/chat_server');
chatServer.listen(server);
cs

이제 lib디렉토리에 chat_server.js 파일을 생성하고 다음 변수 선언문을 가장 앞에 추가합니다. 이 선언문은 Socket.IO의 사용과 상태를 정의하는 여러 변수의 초기화와 관련된 내용입니다.

chat_server.js

1
2
3
4
5
6
7
var socketio = rerquire('socket.io');
var io;
var guestNumber = 1;
var nickNames = {};
var namesUsed = [];
var currentRoom = {};
 
cs

 

▷연결 맺기 로직

이제 로직을 추가해 서버 함수인 listen을 정의합니다. 이 함수는 server.js에서 호출하며 Socket.IO 서버를 시작하고 Socket.IO가 콘솔에 출력하는 로깅을 제한하며 유입되는 연결을 처리하는 방법을 담고있습니다. 연결 처리 로직은 수많은 헬퍼 함수를 호출하며 chat_server.js에 바로 추가할 수 있습니다.

chat_server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
exports.listen = function(server) {
  io = socketio.listen(server);
  io.set('log level', 1);
 
  io.sockets.on('connection', function(socket){
    guestNumber = assignGuestName(socket, guestNumber, nickNames, namesUsed);
    joinRoom(socket, 'Lobby');
 
    handleMessageBroadcasting(socket, nickNames);
    handleNameChangeAttempts(socket, nickNames, namesUsed);
    handleRoomJoining(socket);
 
    socket.on('rooms', function() {
      socket.emit('rooms', io.sockets.manager.rooms);
    });
    handleClientDisconnection(socket, nickNames, namesUsed);
  });
};
cs

 

2행 : 기존의 HTTP 서버에 피기백방식으로 SocketIO서버를 시작

5행 : 각 연결을 어떻게 처리해야 할지 정의

6행 : 사용자가 접속하면 손님 닉네임을 부여

9~11행 : 사용자의 메시지, 닉네임 변경, 채팅방 생성이나 변경에 관한 처리를 수행

13행 : 요청 시 이미 생성된 채팅방 목록을 사용자에게 제공

16행 : 사용자가 접속을 끊었을 때 관련 데이터 정리를 위한 로직을 정의

 

연결 처리에 관한 내용을 완료했다면 이제 어플리케이션의 요구 사항을 처리할 수 있는 각 헬퍼 함수를 추가해야 합니다.


출처 : Node.js 인 액션 

(3부에서 계속)

 

 

 


'Language > Node' 카테고리의 다른 글

2.다중 채팅방 만들기  (0) 2017.08.29
1.Node(노드)란? (2부)  (0) 2017.08.29
1.Node(노드)란?  (0) 2017.08.28

안녕하세요 백자까입니다. 이번에는 javascript의 조건문에 대해서 알아보겠습니다.


조건문은 특정한 조건을 만족하는지 여부를 계산하여 조건을 만족한다면 프로그램 구문을 수행되도록 설정할 수 있습니다. 또한 여러 조건을 설정한 후 그 중 만족하는 조건을 찾을 수 있으며 모든 조건을 만족하지 않을 때 구문이 수행되도록 설정할 수 있습니다.



if문

1
2
3
4
5
6
var a = 10;
var b = 20;
 
if(a < b) {
    documnet.write("a가 b보다 작습니다.");
}
cs


if()를 호출하고 a가 b보다 작다면 이라는 조건을 만족한다면 {}안에 구문이 호출됩니다. a는 b보다 작기 때문에 그 아래 조건을 만족하여 document에 "a가 b보다 작습니다."라고 출력됩니다.



if, else문

1
2
3
4
5
6
7
8
var a = 10;
var b = 20;
 
if(a > b) {
    document.write("a가 b보다 큽니다.");
} else {
    document.write("a가 b보다 작습니다.");
}
cs


if()를 호출하고 a가 b보다 작다는 조건을 만족한다면 {} 안에 구문이 호출되고 그렇지 않으면 else의 {}가 호출됩니다. a는 b보다 작기 때문에 if의 조건을 만족하지 않아 else구문이 호출되어 document에 "a가 b보다 작습니다."라는 메시지가 출력됩니다.



if, else if, else문

1
2
3
4
5
6
7
8
9
10
11
var a = 10;
var b = 20;
var c = 30;
 
if(a > b) {
    document.write("a가 b보다 큽니다.");
} else if( b > c) {
    document.write("b가 c보다 큽니다.");
} else {
    document.write("모든 조건을 만족하지 않습니다.");
}

cs


5, 7라인의 조건은 만족하지 않기 때문에 조건문안의 구문이 실행되지 않습니다. 9, 11번은 조건을 만족하지만 9번의 조건문 안의 구문만 호출됩니다. 그 이유는 조건은 위부터 순차적으로 조건을 비교하며 만족하는 조건이 있으며 더 이상 비교하지 않기 때문에 위의 예를 실행 하면 10번 라인의 구문만 실행됩니다.



조금 특별한 조건문 ?


조건문을 조금 더 간결하게 사용할 수 있습니다. else if없이 if와 else만 사용한다면 조금 더 간결하게 작성할 수 있습니다.

1
(a > b) ? document.write("a는 b보다 큽니다.") : document.write("a는 b보다 작습니다.");
cs
위의 예는 if와 else문을 좀 더 간결하게 작성합니다. '?' 뒤가 조건을 만족할 때 이고, ':' 뒤가 조건을 만족하지 않을 때입니다.



참고서적 : JavaScript+jQuery입문+실전북


'Language > Javascript' 카테고리의 다른 글

6.javascript 반복문  (0) 2017.09.22
5.javascript객체  (0) 2017.09.22
2.Javascript 연산자  (0) 2017.09.19
1.Javascript변수  (0) 2017.08.15
Window 객체  (0) 2017.07.20



이번에는 연산자에 대해서 알아보겠습니다.


연산자는 값을 계산하거나 증가 또는 감소 그리고 문자열을 이어 붙이는 등 다양한 연산을 처리합니다.

다음은 연산자들을 정리한 표 입니다.


종류 

설명 

예시 

+,-,*,/ 

숫자 연산 

사칙연산을 수행합니다.

 +

문자열 연산 

문자열을 이어줍니다. 

%

숫자 연산 

나머지 값을 구합니다. 

++ 

숫자 연산 

1씩 증가합니다.

--

숫자 연산 

1씩 감소합니다. 

 +=,-=,*=,/=,%=

숫자 연산 

연사을 수행하고 값을 대입합니다.


그럼 연산자를 사용한 예를 들어 보겠습니다.

1.사칙 연산

1
2
3
4
5
6
var a = 10;
var b = 20;
var c = 30;
var d = 40;
var e = 50;
var result = a + b - c*d/e;
cs

결과 값 : 10 + 20 - 30*40/50 = 6



2.문자열 연산

1
2
3
var a = "baekjakka";
var b = "tistory";
var result = a + b;
cs

결과 값 : baekjakkatistory



3. 문자열 + 숫자 연산

1
2
3
4
var a = "baekjakka";
var b = 1;
var c = "tistory";
var result = a + b + c;
cs

결과 값 : baekjakka1tistory 

문자열과 숫자를 +연산하면 문자열끼리 연산하는 겻과 같이 연산합니다.


비교 연산자

조건문의 조건을 만들기 위해서는 비교연산자를 사용해야 합니다.


연산자

사용 예 

설명 

 ==

 a == b 

 a와 b가 같다면 

 != 

 a != b 

 a와 b가 다르면 

 && 

 a == b && a == c 

 a와 b가 같고 a 와 c가 같다면, 두 조건이 모두 참이어야 합니다. 

 ||

 a == b || a == c 

 a와 b가 같거나 a 와 c가 같다면, 두 조건 중 하나라도 만족해야 합니다. 

 >

 a > b 

 a 가 b보다 크다면 

 < 

 a < b 

 a가 b보다 작으면 

 >= 

 a >= b  

 a가 b보다 크거나 같으면 

 <=  

 a <= b 

 a가 b보다 작거나 같으면 



** 논리곱과 논리합 연산 부가 설명 **

논리곱(&&) 와 논리합(||)


&& 논리곱은 좌측 표현식의 평가가 false일 경우 우측 표현식은 실행되지 않는다.

|| 논리합은 좌측 표현식의 평가가 true일 경우 우측 표현식은 실행되지 않는다.


실습 예제로 살펴 보겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
&& 와 ||을 이용한 조건문
 
var arr;
 
//arr이 undefined일 경우 비어있는 배열 객체를 대입합니다.
arr=arr || [];
 
arr[0] = "홍길동";
arr[1] = "홍길서";
arr[2] = "홍길남";
arr[3] = "홍길북";
 
//arr이 배열 객체가 존재할 경우 arr 배열의 길이를 출력합니다.
arr && document.writeln("arr.length: " + arr.length + "<br/>");
cs







참고서적 : JavaScript+jQuery입문+실전북

코드작성 : https://colorscripter.com/

'Language > Javascript' 카테고리의 다른 글

5.javascript객체  (0) 2017.09.22
3.javascript 조건문  (0) 2017.09.19
1.Javascript변수  (0) 2017.08.15
Window 객체  (0) 2017.07.20
오브젝트모델(Object Model)  (0) 2017.07.20

이번에는 Git에 대한 사용법을 먼저 익히고 싶은 사람들을 위한 글입니다. 그래서 명령어를 중심으로 글을 작성하겠습니다.

우선 Git을 먼저 다운받도록 하겠습니다. Git(https://git-scm.com/) Git 홈페이지를 들어가서 Git을 다운 받으시면 됩니다.

 

 

그럼 Git이 설치 되었다는 가정하에 진행하도록 하겠습니다.

 

Git을 이용해서 GitHub와 연동되어 사용을 하고 싶은 분들이 많을 것이라고 생각됩니다.

그럼 우선 GitHub에 가서 로그인을 하고 난 다음에 Start a project 버튼을 눌러주도록 합니다.

 

 

그러면 아래와 같은 페이지가 나타나게 됩니다.

 

그러면 Repository name에 저장할 이름을 설정해 주고 Description 에 이 저장소에 대한 설명을 작성해주고 생성해 주면 됩니다.

그리고 나면 아래와 같은 페이지가 나오는데 첫번째 칸(빨간 네모칸)에 쓰여있는 명령어대로 실행을 해주시면 됩니다.

아니면 이미 저장소가 있다면 두번째 칸(파란 네모칸)에 쓰여있는 명령어를 이용하면 됩니다.

일일이 쓰기 귀찮으면 옆에 복사버튼이 있으니 누르고 CMD창에서 붙여넣기만 해주면 됩니다.

 

GitHub에서의 준비는 이것으로 끝입니다. 저장소만 만들어 주면 됩니다. 간단하죠?

그럼 이제 D드라이브로 이동해서 작업할 폴더하나를 만들겠습니다. GitHub와 연동해보도록 하겠습니다.

먼저 CMD창을 열어 명령어를 순서대로 작성을 하면됩니다.

 

 

1
2
3
4
5
6
7
8
9
d:                //D드라이브로 이동합니다
mkdir Git_test    //mkdir은 폴더를 생성하는 명령어 입니다. Git_test 라는 이름의 폴더를 생성합니다.
cd Git_test        //cd는 디렉토리를 이동할 수 있는 명령어입니다. Git_test 폴더로 이동합니다.
echo "#Git_test" >> README.md    //내용이 #Git_test인 README.md라는 파일을 생성합니다.
git init        //현재 폴더에 git저장소를 생성합니다.
git config user.name "YOUR NAME" //사용자명을 등록하는데 꼭 작성해줘야합니다.
git config user.email "YOUR EMAIL" //사용자의 이메일을 등록하는데 꼭 작성해줘야합니다.
git add README.md  //git이 README.md라는 파일을 추적하도록 스테이징 영역에 올려줍니다. 쉽게말하면 git은 add된 것만 관심을 가집니다.
git commit -"first commit" // -m 옵셥을 이용해서 커밋할 때 변경사항에 대한 메시지를 작성할 수 있습니다.
cs

 

 

remote add origin " 깃허브 저장소 " 를 적어주면 되는데요 빨간 네모칸에 쓰여있는 내용그대로인데 길어서 쓰기 귀찮다면 위쪽에 https|SSH 로 되어있는 이곳의 오른쪽에 복사할수 있는 버튼이 있습니다. 그 버튼 눌러다 붙여넣기를 해도 됩니다.

 

1
2
git remote add origin https://github.com/SeungHyunBaek/Git_test.git    //원격저장소를 추가합니다. github에 저장할 저장소입니다.

                                                                      //origin은 추가하는 원격저장소의 이름입니다.

git push -u origin master    //작업한 내용들을 github에 저장합니다.

cs

    

그러면 아래처럼 github에 commit했던 부분까지 원격저장소에 저장된 것을 볼 수 있습니다. 간단하죠?

 

 

초간단 Git 사용방법이었습니다.

'Git' 카테고리의 다른 글

Commit 메세지 작성 : Fix 편  (0) 2020.02.18
1.Git 시작하기  (0) 2017.08.30

안녕하세요 백자까입니다. 오늘은 네트워크에 대해서 알아보겠습니다.

 

○ 네트워크 공부를 시작했지만 어디서 무엇부터 공부해야 좋을지 모르겠다는 사람

○ 과거에 네트워크 책을 많이 읽었지만 내용이 어려워서 포기한 사람

○ 스위치, 라우터, 보안, PI 전화에서 무선 LAN까지 넓게 공부하고 싶은 사람

○ 네트워크의 각 기술이 아닌, 네트워크 전체와 실무에서의 상황을 알고 싶은 사람

○ 깊이 있는 기술까지는 아니더라도 대화가 가능한 수준 정도는 되었으면 하는 사람 

 

이런 분들이라면 이 네트워크 카테고리의 글이 공부하는데 도움이 될 것입니다.

 

● 누가 네트워크를 사용하는가?

먼저 네트워크는 누가 사용하는가에 따라 크게 두가지로 나눌 수 있습니다. 바로 일반사용자와 법인용입니다.

일반 사용자 : 회사나 학교에서 집으로 돌아와 PC를 켜고 네트워크에 '개인'으로 접속하면 일반 사용자가 되는 것입니다.

법인용 : 반대로 회사에 출근하여 네트워크에 접속하면 '회사원'으로써 사용하면 법인용 네트워크 사용자가 됩니다.

 

● 가정용과 기업용의 차이

가정용과 기업용의 차이는 크게 두가지가 있습니다.

 1. 사용자가 사용하는 어플리케이션의 종류 (어플리케이션 : 전자 우편 소프트 or 웹 브라우저와 같은 사용자가 이용가능한 소프트웨어)

 2. 네트워크의 물리적 규모

가정용 네트워크 : 네트워크 인프라 부분에 ADSL이나 광회선 등의 액세스 회선을 이용해 인터넷을 사용하는 경우가 대부분입니다.

기업용 네트워크 : 네트워크 인프라 부분에 인터넷 회선만이 아닌 사내 전용 내선 전화망이나 IP 네트워크망이 존재합니다. 또한, 인터넷 접속 이외에 거점 간 통신도 추가 됩니다.

 

가정용과 기업용 네트워크에는 규모 면에서 커다란 차이가 있습니다. 이에 따라 네트워크 기기의 사양도 달라지는데, 기업용 기기에는 그만큼 고성능과 신뢰성이 요구됩니다. 기기의 가격도 고가이며 보안 측면의 고려가 필요해지는 등의 도입 작업도 복잡합니다. 법인으로서의 사회성도 요구 됩니다.

※사회성 : 기업 활동을 통한 공헌, 예을 들어 네트워크를 구축하는 회사라면 '사람과 사람을 안심하고 연결할 수 있는 네트워크 구축' '편리하고 풍족한 사회를 만든다.' 라는 것을 나타낸다. 수익을 확보하고 사업을 계속 이어가는 것만이 기업의 목적은 아닌 것이다.

 

● 서비스 프로바이더 네트워크

기업용 네트워크로는 별개의 네트워크가 존재합니다. 그것은 서비스 프로바이더용 네트워크와 기업 전용 네트워크입니다. 기업전용 네트워크는 엔터프라이즈 네트워크라고도 합니다.

서비스 프로바이더용 네트워크 : 통신 사업자나 ISP의 네트워크를 말합니다. 이것은 통신 캐리어 사업자용 네트워크라고도 합니다. 대표적인 통신 캐리어 사업자로 KT,SK텔레콤,LG유플러스가 있습니다.

그리고 네트워크 형태에서 보면 WAN의 부분이 됩니다. WAN 회선을 법인 기업용으로 제공하기 위해 네트워크를 구성합니다. 구축할 네트워크는 규모가 크고 들어가는 네트워크 기기도 고도의 성능과 높은 신뢰성이 요구됩니다.

※WAN : LAN과 LAN을 연결하는 대규모 네트워크.

 

기업 전용 네트워크 : 위에서 설명한 그대로지만, 이것을 세분화하면 업종별로 나눌 수 있습니다. 예를들어 금융업이라면 보안을 고려한 기밀성이 높은 네트워크 구성이 대전제로서 구축될 것이고, 제조업라면 CAD 데이터 등 대용량 데이터를 송신하는 경우가 있을 것입니다. 그러므로 대용량 처리를 위한 회선 확보나 음성과 데이터의 우선순위를 정하는 등을 고려한 네트워크를 만드는 것이 중요한 열쇠가 됩니다.

이와 같이 업종에 따라 네트워크에 대한 접근 방법이 조금씩 다릅니다 그러나 어떤 형태의 네트워크라도 사용되는 기기의 기술 기반은 같습니다. 즉, 네트워크의 최대 사명인 사용자로부터 만들어진 데이터를 상대방에게 전달이라는 기본은 어떤 형태의 네트워크에서든 동일합니다. 그러므로 서두르지 않고 네트워크의 기초를 정확히 아는 것부터 시작하도록 해야 합니다.

 

SUMMARY

· 네트워크는 이용하는 입장에 따라 일반 이용자와 법인용으로 나누어집니다.

· 네트워크는 이용하는 장소에 따라 가정용과 기업용으로 나누어집니다.

· 가정용과 기업용의 차이는 다음의 두 가지가 있습니다.

   1.사용자가 이용하는 어플리케이션의 종류

   2.네트워크의 물리적인 규모

· 서비스 프로바이더용 네트워크는 기업에 통신회선 서비스(WAN)를 제공하기 위해 통신 사업자나 ISP에 의해 구축됩니다.

 

● LAN/WAN/MAN

네트워크는 범위에 따라 크게 세가지로 나뉩니다.

○ LAN(Local Area Network) - 회사 건물 내부나 가정 내부의 비교적 작은 범위의 컴퓨터 네트워크

○ WAN(Wide Area Network) - 멀리 떨어진 LAN 끼리 이어 주기 위한 것. 기업의 본사와 지사를 연결하는 네트워크처럼 광범위하고 규모가 큰 네트워크를 말합니다. KT나 SKT 등의 통신 사업자망(광역 이더넷, IP-VPN등)을 사용하여 구축된 네트워

○ MAN(Metropolitan Area Network)은 LAN과 WAN의 중간 범위에 위치합니다. LAN의 범위를 지역 레벨까지 확대하여 특정 지역을 담당하는 것.

 

● 인트라넷(사내 인트라넷)

인트라넷(Intranet)이란, 일반적으로 독립적인 사내 네트워크를 말합니다. 인트라넷의 '인트라'는 '내부'라는 의미입니다. 기업 내 인터넷에 도입하고 정보 공유나 업무 지원에 활용하는 것을 목적으로 구축된 시스템입니다. 인트라넷은 현장에서 사내 인트라넷이라고 불립니다. 사내 인트라넷의 범위는 기업 내부가 되고 인터넷은 포함하지 않습니다. 그럼 사내 인트라넷에서는 구체적으로 무엇을 하는가? 일반적으로 기밀성이 높은 업무 어플리케이션이 사내 인트라넷으로 구성되어 운용 가능해집니다.

 

SUMMARY

· 네트워크는 범위에 따라 LAN,WAN,MAN 세가지로 나뉜다.

· LAN은 회사 건물 안이나 가정 등의 비교적 작은 범위의 컴퓨터 네트워크다.

· WAN은 멀리 떨어진 LAN간을 서로 이어주는 통신 사업자망을 이용하여 구축된 네트워크다.

·인트라넷은 인터넷 기술을 이용하여 구축된 기업 내부의 독립적인 네트워크다.

 

이번에는 네트워크 기초에 대해 쉽게 이해할 수 있게 네트워크 전체 구성을 파악해보겠습니다. '나무를 보고 숲은 보지 못한다.' 라는 말이 있듯이 네트워크는 여러 기술들의 집합체이기 때문에 기술 일부분만을 배운다고 해서 이해할 수는 없습니다. 그러므로 네트워크의 전체 구성을 이해한 후 각각의 기술들을 공부하는 것이 중요합니다.

 

● 네트워크의 전체 구성

네트워크 구성은 대규모 거점, 중규모 거점, 소규모 거점으로 구분합됩니다.

대규모 거점은 회사에 비유할 경우, 본사와 자사와 지사를 생각하면 될 것입니다. 대략 다섯 영역 이상으로 한 영역에 200명(또는 200포트) 이상의 규모를 생각하면 됩니다. 일반적으로 서울이나 대전, 부산에 본사와 지사를 구성하는 회사가 많습니다. 이런 경우 일하는 사람이 많아지면 당연히 네트워크 사용자도 많아집니다. 또한, 네트워크 기기의 수도 많아지고 네트워크 구성도 복잡해 집니다.

※포트 : PC나 기기를 네트워크에 접속하기 위한 접속 통로입니다.

 

중규모 거점은 회사로 말하자면 지점 규모입니다. 대략 다섯 영역까지로 한 영역에 100~200명(또는 100~200포트)의 규모를 생각하면 됩니다. 대구, 울산, 세종, 광주에 대입하면 적절합니다.

 

소규모 거점은 대략 세 영역 이내로, 하나의 영역에 50~100명(또는 50~100포트)인 규모를 생각하면 됩니다. 네트워크를 사용하는 사용자도 대규모 거점이나 중규모 거점에 비교해서 적은 편이고, 네트워크 구성도 단순해집니다. 지금까지 설명한 도시 이외의 장소를 생각하면 됩니다.

 

그러나 지금까지 이야기한 내용은 단편적인 예입니다. 예를 들어, 본사 기능과 공장이 목포 지구에 있다면 광주를 중심으로 네트워크가 구성될 수 있습니다. 또는 서울과 대전이 중규모 거점이 되거나 목포 지역에 제한된 네트워크가 될 수도 있습니다. 

 

오늘은 분산 버전 관리 시스템인 Git 에 대해서 알아보도록 하겠습니다.

Git을 통한 프로젝트 관리는 유용하고 많은 도움이 될 것이라 생각됩니다. 저는 Windows환경에서 진행했음을 알려드립니다.

먼저 간단히 진행 순서를 알려드리겠습니다.

 

1. 저장소 생성하기

2. 파일 추가하고 변경하기

3. 새 브랜치 만들기

4. 릴리스에 태그 붙이고 저장소 관리하기

5. 저장소 복제하기

 

위의 과정을 진행하도록 하겠습니다. ( Git 이 다운받아져 있다는 전제하에 진행하겠습니다. )

 

1. 저장소 생성하기

Git 에서 저장소를 생성하는 방법은 간단하지만 서브버전이나 CVS를 사용해왔다면 조금 이상해 보일 수 있습니다. 대부분의 버전 관리 시스템에서 저장소는 자신이 가지고 있는 복사본과 떨어져 존재하지만 Git에서는 작업 트리와 함께 .git 디렉토리에 저장됩니다.

 

그럼 먼저 Git bash를 열고 프로젝트 코드를 저장할 위치를 정할건데요. 프로젝트 이름은 mysite 라고 정하겠습니다. 프로젝트 이름과 같은 디렉토리를 생성하고 디렉토리 안으로 이동한 다음 git init 이라는 명령어를 입력해주면 됩니다.

 

이것으로 끝입니다. 이제 프로젝트를 추적할 수 있는 Git 저장소가 생겼습니다.

이게 전부일리 없다고 생각할지 모르지만 정말로 더 이상 없습니다. Git 저장소를 설정하는 작업은 정말로 간단합니다.

git init 명령어는 .git 디렉토리를 생성하고 여기에 저장소 메타데이터를 모두 저장합니다. 그리고 현재 비어있는 mysite 디렉토리는 저장소에서 체크아웃 할 코드의 작업 트리가 됩니다.

 

2. 파일 추가하기

이제 빈 저장소에 파일을 추가하겠습니다. index.html 파일을 생성하고 헤더와 'Hello World!'란 텍스트를 추가합니다.

index.html

1
2
3
4
5
<html>
<body>
 <h1>Hello World!</h1>
</body>
</html>
cs

추적을 시작할 간단한 HTML 페이지다. 계속해서 이 파일에 내용을 추가합니다.

이제 추적할 파일이 생겼으니 Git에게 이 파일을 추적하겠다는 사실으르 알립니다.

Git에게 알리는 작업은 두 단계에 걸쳐서 진행됩니다. 먼저 git add 명령어로 HTML 파일을 Git의 관리 목록에 추가합니다. 그러고 나서 git commit으로 커밋합니다.

 

 

 

 추적 하려는 파일이나 파일의 목록을 git add에 매개변수로 전달합니다. 그리고 git commit은 커밋을 생성합니다.

커밋은 저장소에 저장된 개별적인 이력으로, 각 커밋은 코드의 진행 상태를 기록합니다. Git은 앞에서 설정한 내용을 참조해서 사용자의 이름과 이메일 주소를 기록하고 각 커밋에 메시지를 추가합니다.

 앞의 명령어에서 -m 다음의 문자열이 커밋에 추가되는 메시지입니다. 잘 작성한 로그 메시지는 모든 버전 관리 시스템의 핵심 요소로, 로그 메시지에 커밋하는 이유를 설명합니다. 새 파일이 무엇을 하는지? 코드에서 무엇을 변경했는지? 를 알 수 있습니다.

 git log 를 실행하면 지금까지의 커밋 내용을 볼 수 있습니다.

 

 

 

첫 줄에서 커밋명을 보여줍니다. 커밋명은 커밋을 추적할 수 있도록 Git이 생성한 SHA-1 해시(hash) 값입니다. Git은 각 커밋의 식별자가 완벽히 고유하도록 SHA-1 해시를 이용합니다. 분산 환경에서는 완벽히 고유하다는 점이 중요합니다.

git log 출력의 둘째 줄은 커밋한 사람의 정보입니다. 셋째 줄은 커밋한 날짜고, 마지막 줄은 커밋 로그 메시지입니다.

 

3. 프로젝트를 이용한 작업 시작하기

이제 저장소를 준비했으며 이미 첫 번째 파일을 추적하고 있습니다. 이제부터 변경 사항을 다뤄보겠습니다.

지금까지 HTML에 <head>와 <title> 엘리먼트가 빠져 있었습니다. 엘리먼트를 추가한 index.html 파일은 다음과 같습니다.

index.html

1
2
3
4
5
6
7
8
<html>
<head>
 <title>Hello World in Git</title>
</head>
<body>
 <h1>Hello World!</h1>
</body>
</html>
cs

 

방금 파일을 변경했음을 Git도 알고 있습니다. git status 명령어는 저장소의 현재시점인 작업 트리의 상태를 보여줍니다.

서브버전이나 CVS 사용자는 작업 트리를 작업 복사본이라고 알고 있습니다.

 

 

출력 결과를 통해 변경된 파일을 Git이 알고 있지만 이를 어떻게 처리할지는 아직 모른다는 사실을 알 수 있습니다.

변경한 파일은 수정된 파일(modified)로 표시되지만, 갱신 전(Changed but not updated) 헤더에 있습니다. 이 파일을 커밋하려면 변경 사항을 스테이징(stage)해야 합니다. 변경 사항을 스테이징하면 커밋할 수 있도록 준비합니다. Git에서는 사용자의 코드를 세 곳에 저장합니다.

첫째 위치는 파일을 편집할 때 직접 이용하는 작업트리다.

둘째 위치는 인덱스이며 이후에는 스테이징 영역(staging area)이라 부릅니다. 스테이징 영역은 작업 트리와 저장소 사이의 버퍼(buffer)공간입니다.

마지막 위치는 Git이 코드를 저장하는 저장소입니다. 스테이징 영역은 저장소에 커밋하려는 대상만 올려두는 용도로 사용합니다.

이제 git add 명령어를 다시 이용하면 index.html 파일의 변경 내용을 스테이징할 수 있습니다. 이전에 새 파일을 추가하기 위해서 사용한 명령어와 동일합니다. 다만 새로운 파일임을 알리는 용도가 아니라 추적할 새로운 변경 내용이 있음을 Git에게 알립니다.

 

 

수정된 index.html 파일을 추가한 다음 git status 명령어를 실행하면 헤더 영역이 갱신 전에서 커밋 예정(Changes to be commit-ted)로 바뀐 것을 확인할 수 있습니다. 색상 출력을 켜놨다면 index.html을 가리키는 줄의 색이 빨간색에서 녹색으로 바뀐 것도 볼 수 있습니다.

그럼 git commit 명령어를 실행해보겠습니다. 이때, -m 매개변수를 이용해서 변경한 이유를 설명한 것도 잊지 말아야합니다.

 

 

두 개의 -m 매개변수를 사용했습니다. Git에서는 원하는 대로 -m 매개변수를 사용할 수 있고, 매개변수마다 하나의 문단으로 취급합니다.

git log로 메시지가 두 개의 문단으로 구성됨을 확인할 수 있습니다.

 

 

git log 명령어에 새로운 매개변수 -1을 이용했습니다. 숫자를 변경하면 보고 싶은 커밋 개수만큼 git log의 출력을 제한할 수 있습니다.

 

4.브랜치 사용하고 이해하기

브랜치를 이용하면 작업 중인 프로젝트의 분기 이력을 관리할 수 있습니다. 분기 이력이 훌륭하긴 하지만 실제 프로젝트에서는 어떻게 사용해야 할까요? 실제 유용한 형태의 브랜치는 두 가지가 있습니다. 바로 프로젝트의 여러 버전을 브랜치 별로 관리하기 위해 생성한 브랜치와 특정 기능을 다루는 주제 브랜치입니다. 저는 첫번째 형태의 브랜치를 다루도록 하겠습니다.

mysite코드는 릴리스 준비가 거의 끝났지만 그래도 관련된 사람들에게 승인을 받아야 합니다. 승인을 기다리는 중에도 다음 버전의 새로운 기능을 추가할 수 있습니다.

브랜치를 이용하면 릴리스 준비가 된 코드의 복사본을 보관해둘 수 있으므로 개발을 멈출 필요가 없습니다. 브랜치를 생성하는 명령어는 git branch이며 매개변수를 두 개 받습니다. 첫번째는 생성하려는 브랜치명이고 두번째는 분기해 나올브랜치명입니다.

 

 

이 명령어는 master 브랜치에서 RB_1.0이라는 브랜치를 생성합니다. Git에서 master는 기본 브랜치명입니다. CVS나 서브버전에서는 Git의 master 브랜치와 같은 역할을 트렁크(trunk)라고 부릅니다. 브랜치명에서 사용한 RB는 릴리스 브랜치(release branch)의 약어입니다. RB라는 접두어를 붙이면 릴리스 브랜치를 파악하기 쉬워집니다.

이제 릴리스 준비 중인 코드에 영향을 주지 않고도 내용을 변경할 수 있습니다. index.html 파일에 약력(Biography) 페이지로 가는 링크를 추가합니다.

</body> 태그 앞에 다음 내용을 추가합니다.

 

index.html

1
2
3
4
5
6
7
8
9
10
11
<html>
<head>
 <title>Hello World in Git</title>
</head>
<body>
 <h1>Hello World!</h1>
 <ul>
  <li><a href="bio.html">Biography</a></li>
 </ul>
</body>
</html>
cs

 

이제 변경사항을 커밋하겠습니다. 이전과는 조금 다른 형태의 명령어를 사용합니다.

 

 

 

출처 : Git, 분산버전관리시스템

 

 

 

'Git' 카테고리의 다른 글

Commit 메세지 작성 : Fix 편  (0) 2020.02.18
초간단 Git 사용법  (0) 2017.09.08


이번에는 단순한 이베트 주도 방식의 채팅 어플리케이션을 만들어 보면서 노드의 실용적인 측면을 살펴보도록 하겠습니다. 이번에 소개하는 상세한 내용 때문에 머리가 아프더라도 너무 걱정할 필요는 없습니다. 목적은 노드 개발에 대한 궁금증을 풀고 노드로 무엇을 할 수 있을지를 미리 본다고 생각하면 됩니다.

웹 어플리케이션을 개발해 본 경험이 있고 HTTP에 대한 기본적인 이해가 있으며 jQuery에 친숙하다는 전제하에 글을 쓰겠습니다.

먼저 진행 내용은 이렇습니다.

○ 어플리케이션의 동작 방식을 살펴본다.

○ 기술적인 요구사항을 살펴보고 어플리케이션 초기 설정을 진행합니다.

○ 어플리케이션에서 사용할 HTML, CSS, 클라이언트 측 자바스크립트를 서비스합니다.

○ Socket.IO를 이용해 채팅과 관련된 메시지를 처리합니다.

○ 어플리케이션 UI에 사용할 자바스크립트를 작성합니다.

 

▷어플리케이션 개요

만들 어플리케이션은 여러 사용자가 대화창에 메시지를 입력해 온라인에서 채팅할 수 있는 프로그램입니다. 한 사용자가 메시지를 입력하면 다른 모든 사용자에게 전송됩니다. 어플리케이션이 시작될 때 각 사용자에게 자동으로 닉네임이 주어지지만, 특정 명령어를 이용해서 닉네임을 변경할 수 있습니다. 닉네임을 변경하기 위한 채팅 명령어는 슬래시(/)로 시작합니다. 비슷한 방식으로 새로운 채팅방을 만들거나 기존 방에 참여할 때 채팅 명령어를 사용할 수 있습니다. 채팅방을 만들거나 참여하면 어플리케이션 상단의 가로 막대 영역에 새롭게 참여한 채팅방의 이름이 표시됩니다. 또한, 대화창 오른쪽에 있는 참여할 수 있는 모든 채팅방 목록에도 현재 채팅방의 정보가 표시 됩니다.

 

이 어플리케이션은 가장 단순한 기능만 있지만, 실시간 어플리케이션을 만드는데 필요한 주요 컴포넌트와 기반 기술을 소개하고 있습니다. 특히, 노드가 어떻게 정적 파일과 같은 일반적인 HTTP 데이터와 대화 내용과 같은 실시간성 데이터를 동시에 서비스 하는지 알 수 있습니다. 또한, 노드 어플리케이션의 구성 방식과 의존성 모듈 관리 방식도 보여줍니다.

 

▷어플리케이션 요구사항과 초기 설정

채팅 어플리케이션을 위해서는 다음과 같은 작업을 수행해야 합니다.

○ 정적 파일 서비스(HTML, CSS와 클라이언트 측 자바스크립트 등)

○ 서버에서 채팅과 관련된 메시지 처리

○ 사용자 브라우저에서 채팅과 관련된 메시지 처리

 

정적 파일을 서비스 하려면 노드에 포함된 HTTP 모듈을 사용해야 합니다. 또한, HTTP를 이용해 파일을 서비스 한다면 파일 내용뿐만 아니라 전송되는 파일의 종류도 포함하여 전송해야 합니다. 이 정보는 HTTP 헤더의 Contet-Type에 설정할 수 있으며 파일의 적절한 마임(MIME) 형식을 헤더에 추가해줍니다. 마임 형식은 mime이라는 서드파티 모듈을 사용해서 둘러 볼 수 있습니다.

mime : 전자 우편을 위한 인터넷 표준 포멧입니다. HTTP와 같은 통신 프로토콜에 사용되고 있습니다. 

(자세한 내용은 위키피디아 참고 : https://ko.wikipedia.org/wiki/MIME)

 

채팅과 관련되 메시지를 처리하기 위해 ajax를 이용해 서버로부터 데이터를 가져올 수 있습니다. 하지만 어플리케이션이 가능한 빨리 반응하게 하려면 기존의 ajax 방식을 사용해 메시지를 전송하는 방법을 피해야 합니다. ajax가 전송 체계로 사용하는 HTTP는 실시간 통신을 위해 설계된 것이 아닙니다. HTTP를 이용해 메시지를 전송하면 매번 새로운 TCP/IP 연결을 사용해야 합니다. 연결을 시작하고 종료하는데 시간이 소요되며 모든 요청마다 HTTP 헤더 정보를 보내야 하므로 전송해야 할 데이터 양도 많아지게 됩니다. 그러므로 HTTP보다는 실시간 통신을 지원하기 위해 설계된 양방향 경량 통신 프로토콜인 웹소켓을 이용하는 편이 더 좋습니다.

하지만 웹소켓을 사용하지 못하는 브라우저가 있을 때 다양한 대체 기능을 제공하는 인기 라이브러리인 Socket.IO를 활용해서 어플리케이션을 만들도록 하겠습니다. Socket.IO는 추가 코드나 설정 없이 대체 기능을 투명하게 처리합니다.

 

▷HTTP와 웹소켓 서비스

본격적으로 시작하기 전에 HTTP와 웹소켓을 동시에 처리하는 방법을 조금 알아보겠습니다. 이는 노드가 실시간 어플리케이션에 적절한 선택이 될 수 있는 이유이기도 합니다. 어플리케이션에서 채팅 메시지를 주고받을 때 ajax를 사용하지 않기로 했지만, 사용자의 브라우저에 그릴 화면을 보여줄 때 필요한 HTML, CSS, 클라이언트 측의 자바스크립트를 전송하려면 여전히 HTTP를 사용해야 합니다. 노드는 하나의 TCP/IP 포트를 이용해 HTTP와 웹소켓을 동시에 쉽게 서비스합니다. 노드 내부에는 HTTP 서비스를 제공하는 모듈이 있는데 익스프레스와 같이 노드의 내장 기능을 이용해 웹 서비스를 조금 더 쉽게 할 수 있도록 도와주는 서드파티 모듈이 많이 있습니다.

 

▷어플리케이션의 파일 구조 생성

어플리케이션을 제작하기에 앞서 프로젝트 디렉토리를 생성합니다. 주요 어플리케이션 파일이 디렉토리에 바로 저장됩니다.

 

 

 

lib : 서버 측 로직을 구현한 파일을 저장

public : 클라이언트 측과 관련된 파일을 저장

 ├ javascripts

 └ stylesheets

 

구조를 이렇게 만들었지만 노드는 특정 디렉터리 구조만을 고집하지 않습니다.

사용자가 생각하는 어떤방식으로도 어플리케이션 파일을 관리할수 있습니다.

디렉터리를 모두 생성했으면 어플리케이션의 의존성 모듈을 명시하는 방법을 자세히 알아보겠습니다.

 

 

▷의존성 모듈 명시

어플리케이션 의존성 모듈이란 어플리케이션에 필요한 기능을 사용하기 위해 설치해야 하는 모듈을 말합니다. 예를들어, MySQL 데이터베이스에 데이터를 저장하는 어플리케이션을 만들었다고 가정해보겠습니다. 노드 내부에는 MySQL에 접근할 수 있는 내장 모듈이 없으므로 이를 위한 서드파티 모듈을 따로 설치해야 하는데 이를 의존성 모듈로 볼 수 있습니다. 물론 의존성 모듈을 형식에 맞게 명시하지 않더라도 노드 어플리케이션을 만들 수 있지만, 의존성 모듈을 명시하는 것은 좋은 습관입니다. 의존성 모듈을 명시함으로써 다른 사용자가 어플리케이션을 사용하거나 여러 곳에서 프로그램을 실행해야 할 때 좀더 수월하게 사용 환경을 설정할 수 있습니다.

 

어플리케이션 의존성 모듈은 package.json 파일에 명시합니다. 이 파일은 항상 어플리케이션의 최상위 디렉터리에 있어야 합니다.

package.json 파일은 CommonJS 패키지 기술어 표준을 따르는 JSON 표현식을 사용하며 어플리케이션에 대한 설명을 담고 있습니다.

 

package.json

1
2
3
4
5
6
7
8
9
{
  "name" : "chatrooms",
  "version" : "0.0.1",
  "description" : "Minimalist multiroom chat server",
  "dependencies" : {
    "socket.io" : "~0.9.6",
    "mime" : "~1.2.7"
  }
}
cs

 

이 파일의 내용이 혼란스럽더라도 걱정할 필요는 없습니다. 그냥 단순히 어플리케이션의 정보를 담고 있는 파일이라고 생각하시면 됩니다.

name : 어플리케이션의 이름입니다.

version : 어플리케이션의 버전정보를 말해주는데 첫 버전이니 0.0.1로 설정했습니다.

description : 영어만 봐도 알 수 있듯이 어플리케이션의 대한 설명입니다.

dependencies : 의존성 모듈을 나타내는데요. 이 곳에 적힌 모듈을 확인해서 필요한 모듈을 설치할 수 있습니다. 반대로 필요한 모듈을 설치 받았을 때에 자동으로 이곳에 작성되기도 합니다.

 

그럼 이제 cmd창을 열어 우리가 만든 최상위 폴더로 이동해줍니다. cmd창에서 폴더를 이동하는 명령어는 cd 명령어 입니다.

최상위 폴더로 갔다면 npm install 이라는 명령어를 실행해봅니다.

 

디렉토리 구조를 만들고 의존성 모듈을 설치했으니 이제 어플리케이션 로직에 살을 붙일 준비가 되었습니다.

 

 

▷HTML, CSS, 클라이언트 측 자바스크립트 서비스

앞서 말했듯이 3가지 기능이 필요합니다.

○ 정적 파일 서비스(HTML, CSS와 클라이언트 측 자바스크립트 등)

○ 서버에서 채팅과 관련된 메시지 처리

○ 사용자 브라우저에서 채팅과 관련된 메시지 처리

 

먼저 정적파일을 서비스하기 위한 로직을 만들어 보겠습니다. 그리고 정적 HTML과 CSS파일을 추가하겠습니다.

정적 파일 서버를 생성하려면 노드에 내장된 몇가지 기능과 함께 파일의 MIME 타입을 판단할 수 있는 서드파티 mime모듈을 이용합니다.

가장 먼저 할 일은 프로젝트 최상위 폴더에 server.js 파일을 생성합니다.

이 파일은 노드의 HTTP 관련 기능과 파일시스템 연동, 파일 경로와 관련된 기능, 그리고 MIME 타입 판단 기능을 사용할 수 있게끔 합니다.

cache 변수는 캐시 파일 데이터를 다루는데 사용합니다.

server.js

1
2
3
4
5
var http = require('http'); 
var fs = require('fs');
var path = require('path');
var mime = require('mime');
var cache = {};
cs

 

1행 : HTTP 서버와 클라이언트 기능을 제공하는 내장 http 모듈

2행 : 파일시스템 관련 기능을 제공하는 fs 모듈 

3행 : 파일시스템 경로 관련 기능을 제공하는 내장 path모듈

4행 : 파일명 확장자 기반의 MIME 타입 추론 기능을 제공하는 외부 mime 모듈

5행 : 캐시된 파일의 내용이 저장되는 캐시 객체

 

다음으로 할 일은 정적 HTTP 파일 서비스에 필요한 세개의 헬퍼 함수를 작성하는 것입니다.

첫번째는 요청한 팡리이 존재하지 않을 때 404 오류를 전송하는 부분입니다. server.js 에 해당 함수를 추가해 보겠습니다.

1
2
3
4
5
function send404(response) {
  response.writeHead(404, {'Content-Type':'text/plain'});
  response.write('Error 404: resource not found.');
  response.end();
}
cs

 

두번째는 파일 데이터를 서비스하는 함수입니다. 먼저 적절한 HTTP 헤더를 작성한 다음 파일의 내용을 전송합니다. server.js에 작성합니다.

1
2
3
4
function sendFile(response, filePath, fileContents) {
  response.writeHead(200, {'Content-Type' : mime.lookup(path.basename(filePath))});
  response.end();
}
cs

 

파일시스템보다는 메모리 저장 장치(RAM)의 접근 속도가 더 빠릅니다. 이런 이유로 노드 어플리케이션에서는 최근에 사용한 데이터를 일반적으로 메모리에 캐싱합니다. 이번 채팅 어플리케이션에서는 정적 파일을 처음 디스크에서 읽을 때를 제외하고는 메모리에 캐시해 사용할 것입니다.

다음 함수는 캐시에 파일이 존재하는지 판단하여 캐시에 있다면 바로 서비스하고 캐시에 없다면 디스크에서 읽어와서 서비스합니다.

만약 어디에도 파일이 존재하지 않으면 응답으로 HTTP 404 오류를 반환합니다. 함수는 server.js에 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function serveStatic(response, cache, absPath) {
  if (cache[absPath]) {
    sendFile(response, absPath, cache[absPath]);
  } else {
    fs.exists(absPath, function(exists) {
      if(exists) {
        fs.readFile(absPath, function(err, data) {
          if(err) {
            send404(response);
          } else {
            cache[absPath] = data;
            sendFile(response, absPath, data);
          }
        });
      } else {
        send404(response);
      }
    });
  }
}
cs

2행 : 파일이 메모리에 캐시돼 있는지 확인

3행 : 캐시에 존재하는 파일이면 바로 서비스

5행 : 파일 존재 여부 검사

7행 : 디스크에서 파일 읽기

12행 : 디스크에 저장된 파일 서비스

16행 : HTTP 404 오류 응답

 

출처 : Node.js 인 액션

2부에서 계속..

 

 

 

 


'Language > Node' 카테고리의 다른 글

2.다중 채팅방 만들기 (2부)  (0) 2017.09.19
1.Node(노드)란? (2부)  (0) 2017.08.29
1.Node(노드)란?  (0) 2017.08.28

DIRTy 애플리케이션 

DIRT는 노드를 적용하기에 적절한 형태의 어플리케이션인 데이터 집약적 실시간 애플리케이션(data-intensive real-time)의 앞글자를 딴 단어입니다.

노드는 I/O 부분에서 매우 가벼워졌기 때문에 한 파이프에서 다른 파이프로 데이터를 전송하는 프록싱(proxying)이나 셔플링(shuffling)에 적합합니다.

이는 서버가 많은 요청을 처리하는 중에도 여러 개의 연결을 유지할 수 있으며 메모리 공간을 적게 사용하도록 관리되기 때문입니다. 이처럼 노드는 브라우저와 같이 요청에 빠르게 반응하도록 설계됐습니다.


DIRTy의 기본요소

노드는 이벤트 주도와 비동기 방식을 기반으로 만들어졌습니다. 자바스크립트는 일반적인 서버 측 언어와 달리 표준  I/O 라이브러리를 가지고 있지 않다.

자바스크립트의 기반 환경이 이를 제공합니다. 가장 일반적이며 가장 많은 개발자가 사용하는 스크립트 환경은 이벤트주도와 비동기 방식을 사용하는 부라우저입니다. 노드는 다양한 종류의 네트워크 및 파일 I/O에 사용되는 핵심 모듈도 포함하고 있는습니다. 여기에는 HTTP, TLS, HTTPS, 파일시스템(POSIX), 데이터그램(UDP), NET(TCP)에 대한 모듈이 포함되어 있습니다. 핵심 모듈은 I/O 기반의 애플리케이션을 위한 기본적인 구성 요소만을 포함하여 일부러 작고 단순하며 하위레벨로 만들어졌습니다. 이를 기반으로 만들어진 서드파티 모듈은 일반적인 문제에 대한 훌륭한 추상화를 제공합니다.


플랫폼 vs 프레임워크

노드는 자바스크립트 어플리케이션을 위한 플랫폼이며 혼동해서는 안됩니다. 노드에 관한 일반적인 오해는 노드가 훨씬 낮은 계층임에도 불구하고 레일즈(Rails)나 장고(Django) 같은 스크립트의 프레임워크라고 생각하는 것입니다. 


이제는 노드를 이용해서 기본적인 서버를 하나 만들어 보도록 하겠습니다.

언제나 그렇듯 처음 시작할 때는 Hello world가 빠져선 안되겠죠? 그래서 Hello World HTTP 서버를 만들어 보도록 하겠습니다.


Hello World HTTP서버 ( node 설치 방법 )

노드는 일반적으로 서버를 구성하는데 많이 이용됩니다. 노드를 이용해 다양한 종류의 서버를 만드는 것이 매우 간단하기 때문입니다.

이는 아파치 HTTP 서버에서 PHP 어플리케이션을 올리는 것처럼 어플리케이션을 위해서 서버를 따로 두어야 했던 환경에 익숙한 사람에게는 이상하게 들릴 수도 있습니다. 노드에서는 서버와 어플리케이션이 같은 의미입니다.

그럼 모든 요청에 단순하게 'Hello World' 라고 응답하는 HTTP 서버 예제를 만들어 보겠습니다.


helloworld.js

1
2
3
4
5
6
var http = require('http');
http.createServer(function(req, res) {
    res.writeHead(200, {'Content-Type''text/plain'});
    res.end('Hello World\n');
}).listen(3000);
console.log('Server running at http://localhost:3000/');
cs


요청이 들어오면 콜백 함수인 function(req, res)이 호출되어 "Hello World"라는 문장을 응답으로 보낸다. 이러한 이벤트 처리 방식은 브라우저에서 onclick 이벤트를 처리하는 방법과 유사합니다. 클릭은 어떤 부분에서든 발생할 수 있으며 이벤트가 발생했을 때 이를 처리하기 위한 함수를 만들어야 합니다.

이 예제에서 노드는 언제 요청이 들어오든 간에 응답하는 함수를 제공하고 있습니다. 이번에는 좀 더 명확하게 표시해 작성한 예입니다.


helloworld.js

1
2
3
4
5
6
7
var http = require('http');
var server = http.createServer();
server.on('request'function(req, res) {
    res.writeHead(200, {'Content-Type''text/plain'});
    res.end('Hello World\n');
}).listen(3000);
console.log('Server running at http://localhost:3000/');
cs


▷스트리밍 데이터

노드는 스트림과 스트리밍 데이터 처리에도 많이 사용됩니다. 스트림은 배열과 같은 개념으로 생각할 수 있습니다. 다만 데이터가 여러 공간에 걸쳐 분산된 것이 아니라 시간의 흐름에 따라 분산된 것입니다. 쪼개진 데이터 조각이 하나씩 도착하므로 개발자는 데이터 전체가 준비될 때까지 기다렸다가 처리하는 대신 데이터가 도착하는 즉시 처리할 수 있어야 합니다. resource.json 스트림을 어떻게 처리하는지 살펴보도록 하겠습니다.


1
2
3
4
5
6
7
var stream = fs.createReadStream('./resource.json')
stream.on('data'function(chunk) {
    console.log(chunk)
})
stream.on('end',function() {
    console.log('finished')
})
cs

data 이벤트는 새로운 데이터 조각이 만들어질 때마다 발생합니다. 그리고 모든 데이터 조각을 다 읽었을 때 end 이벤트가 발생합니다. 데이터 조각은 크기가 정해져 있지 않으며 데이터의 종류에 따라 다릅니다. 읽기 스트림에 대한 하위레벨의 접근은 메모리 버퍼에 모든 데이터가 쌓일 때까지 기다리는 것보다 훨씬 효율적으로 데이터를 처리할 수 있습니다. 노드는 데이터 조각들을 쓸 수 있는 쓰기 스트림도 제공합니다. 그 중 하나가 바로 HTTP 서버에서 요청이 들어올 때 사용하는 응답(res)객체입니다. 

읽기와 쓰기 스트림은 하나로 연결되어 데이터 파이프를 구성할 수 있는데, 마치 셸 스크립트에서 |(파이프) 연산자를 사용하는 것과 비슷한 방식입니다.

이런 방식은 데이터 전체를 완전히 읽을 때까지 기다렷다가 쓰는 대신, 데이터를 읽어 들이는 즉시 쓸 수 있는 효율적인 방법을 제공합니다.

 

이전의 HTTP서버를 활용해서 클라이언트에 이미지를 스트리밍으로 전송하는 방법을 살펴보겠습니다.

1
2
3
4
5
6
7
8
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
 res.writeHead(200, {'Content-Type''image/png'});
 fs.createReadStream('/image.png').pipe(res);
}).listen(3000);
 
console.log('Server running at http://localhost:3000');
cs

 

이 짤막한 예제에서 파일(fs.createReadStream)로 부터 데이터를 읽는 즉시 클라이언트(res)에게 내보냅니다.(pipe)

이벤트 루프는 데이터가 스트림 되는 도중에도 다른 이벤트를 처리할 수 있습니다.

노드는 이러한 DIRTy의 기본적인 요소를 여러 유닉스와 윈도우를 포함한 다수의 플랫폼에 제공합니다.

특히 기반을 이루고 있는 비동기 I/O 라이브러리는 부모 운영체제와 상관없이 동일한 방식을 제공하므로 기기에 상관없이 프로그램을 이식하기 쉽고 필요할 겨우 다양한 장비에서 실행 할 수 있습니다.

 

▷요약
다른 기술과 마찬가지로 노드 역시 모든 것에 대한 해결책은 아닙니다. 노드는 그저 특정 문제를 해결하는데 도움을 주고 새로운 가능성을 열어 줍니다. 노드에 관해 한 가지 흥미로운 점은 시스템의 모든 분야 사람들에게 관심을 받는 다는 것입니다. 대부분 자바스크립트로 개발하는 클라이언트 측 프로그래머이고 그 외에 서버측 프로그래머와 시스템 레벨 프로그래머도 있습니다. 여러분이 어디에 속해있든 해당 분야에서 노드가 적합한 곳이 어딜지 이해하기 바랍니다. 다시 3줄로 정리해 보겠습니다.

 1. 자바스크립트 기반으로 만들어졌다.

 2. 이벤트와 비동기를 사용합니다.

 3. 데이터 집약적 실시간 어플리케이션을 위해 설계됐습니다.



출처 : node.js 인 액션

'Language > Node' 카테고리의 다른 글

2.다중 채팅방 만들기 (2부)  (0) 2017.09.19
2.다중 채팅방 만들기  (0) 2017.08.29
1.Node(노드)란?  (0) 2017.08.28

 

이번에는 노드에 대해서 알아보도록 하겠습니다. ( 참고서 : Node.js 인 액션 )

 

먼저 노드란 무엇일까요? 노드는 2009년에 첫선을 보였는데요 노드의 공식 웹사이트(http://www.nodejs.org)에서는 노드를 "크롬의 자바스크립트 실행 환경에 기반을 둔 빠르고 확장성 있는 네트워크 애플리케이션을 만들기 위한 플랫폼"이라고 정의하고 있습니다. 노드는 이벤트 주도 방식과 논블럭킹 I/O 방식을 사용하는데, 이는 가볍고 효율적이며 분산 환경에서 실행되는 데이터 집약적인 실시간 애플리케이션에 매우 적합합니다.

 

노드는 자바스크립트 기반입니다

노드는 구글 크롬에 탑재된 V8 가상 머신을 서버 프로그래밍에 사용하는데요 V8은 바이트코드를 실행하거나 인터프리터를 사용하는 중간 과정을 없애고 네이티브 기계어로 컴파일하는 방식으로 노드에 상당한 성능 향상을 가져왔습니다. 또한, 노드가 서버상에서 자바스크립트를 실행하기 때문에 얻을 수 있는 이점이 있습니다.

  • 개발자는 하나의 언어로 웹 애플리케이션을 개발할 수 있기 때문에 서버와 클라이언트를 넘나드는 비용을 줄일 수 있습니다.

  • JSON은 보편적인 데이터 교환 포맷으로 자바스크립트에 바탕을 두고 있습니다.
  • 자바스크립트는 NoSQL데이터베이스에서 사용되는 언어로 상호작용하기에 아주 적합합니다.
  • 노드가 사용하는 V8 가상 머신은 ECMA스크립트 표준을 준수하고 있습니다. 다시 말해, 노드가 사용하고 있는 자바스크립트의 새로운 기능을 모든 브라우저가 지원할 때까지 기다릴 필요가 없습니다.

노드의 환경을 이해하기 위해 먼저 가장 친숙한 자바스크립트 환경인 '브라우저'에 대해서 알아보도록 하겠습니다.

 

☞ 비동기와 이벤트 : 브라우저

노드는 서버 측 자바스크립트에 이벤트 주도 방식과 비동기 플랫폼을 제공합니다. 이는 브라우저가 클라이언트에서 자바스크립트를 사용할 수 있게 한 것 처럼 서버에서 자바스크립트를 사용할 수 있게 합니다. 노드가 동작하는 방식을 이해하려면 브라우저의 동작 방식을 이해하는 것이 중요합니다. 브라우저와 노드 모두 이벤트 주도 방식을 사용하며 논블럭킹 방식으로 I/O를 처리합니다.

 

☞ 비동기와 이벤트 : 서버

대부분 서버 측 프로그래밍의 일반적인 I/O 모델에 친숙할 것이라고 생각이 드는데요 간단히 PHP로 작성한 예를 들어 보겠습니다.

1
2
$result = MYSQL_query('SELECT * FROM myTable');
print_r($result);
cs

 

위 코드에서는 I/O가 실행되고 모든 데이터가 도착할 때까지 프로세스가 멈춥니다. 대부분 어플리케이션에서 이런 방식은 잘 동작하고 따라하기 쉽습니다.

그러나 I/O 실행이 지연되면 어느 부분에서든 10ms에서 수분까지 소요될 수 있습니다. 지연은 예상치 못한 원인에서 비롯될 수 있습니다.

1. 디스크의 유지보수 작업 수행으로 읽기/쓰기가 정지될 때

2. 데이터베이스의 부하가 높아져 질의 수행이 느려질 때

3. 알 수 없는 이유로 sitexyz.com에서 자원을 가져오는 것이 갑자기 느려졌을 때

만약 프로그램이 I/O 대기 중일 때, 서버가 더 많은 요청을 처리해야 한다면 어떻게 될까요? 대체로 이런 상황에서 멀티스레드 접근법을 사용할 것입니다.

일반적인 구현 방법은 하나의 연결당 하나의 스레드를 사용하고 여러 연결을 위한 스레드 풀을 만드는 것인데요 스레드는 프로세서가 하나의 태스크를 처리하기 위한 계산 작업 공간이라고 볼 수 있습니다. 대부분의 경우 스레드는 프로세스 내부에 포함돼 있으며 자신의 작업 메모리를 유지합니다. 그리고 각 스레드는 하나 이상의 서버 연결을 처리합니다. 이는 적어도 오랫동안 이렇게 일해 온 개발자에게는 자연스러운 방법처럼 들리겠지만, 어플리케이션 내부에서 스레드를 관리하는 것은 굉장히 복잡할 수 있습니다. 또한, 많은 수의 서버 연결을 동시에 처리해야 하는 경우라면 스레딩은 운영체제의 자원에 부담을 주게 됩니다. 스레드는 추가적인 RAM을 사용할뿐만 아니라 CPU의 문맥 교환이 필요합니다.

 

이를 설명하기 위해 엔진엑스(NGINX)와 아파치(Apache)를 비교하여 성능을 측정해 볼 수 있습니다.

엔진엑스(NGINX)는 아파치와 같은 HTTP 서버지만 I/O 대기가 있는 멀티 스레드 접근법 대신 브라우저나 노드처럼 비동기 I/O와 이벤트 루프를 사용하고 이러한 방식을 선택함으로써 엔진엑스(NGINX)는 더 많은 요청과 클라이언트 연결을 처리할 수 있게 됐고, 요청에 더욱 빠르게 반응하는 솔루션으로 자리매김했습니다.

 

노드에서 I/O는 대부분 주 이벤트 루프 외부에서 수행되어 엔진엑스처럼 효율적이고 요청에 잘 반응 할 수있는 상태가 되게 합니다. 이런 방식에서 프로세스는 I/O 집약적이기 어려운데 수행이 멈춰진 상태에서도 I/O 지연 때문에 서버가 장애를 일으키거나 자원을 소비하지 않기 때문입니다. 이런 이유로 서버는 일반적으로 수행 성능을 가장 저해하는 부분에서 짐을 덜 수 있게 되었습니다.

 

'Language > Node' 카테고리의 다른 글

2.다중 채팅방 만들기 (2부)  (0) 2017.09.19
2.다중 채팅방 만들기  (0) 2017.08.29
1.Node(노드)란? (2부)  (0) 2017.08.29



이번에는 자바스크립트의 기초에 해당하는 변수에 대해서 알아보겠습니다.


변수에 대해 간단히 설명하자면 변수는 값을 저장하는 역할을 합니다. 

그리고 선언한 변수에 다른 값을 저장하게 되면 기존의 값은 사라지고 새로운 값이 남게 됩니다. 간단하죠? 어렵지 않습니다.


그럼 변수를 선언하는 방법에 대해서 알아보겠습니다.

변수는 사용자가 임의의 단어로 선언할 수 있는데요 변수명을 정할 때 주의할 사항이 있습니다.


변수명 정하기

1. 영어와 숫자 그리고 특수 문자를 혼합하여 지정할 수 있습니다.

2. 한글은 사용할 수 없습니다.

3. 숫자가 맨 앞에 올 수 없습니다.

4. 낙타등표기법(CamelCase)을 사용하면 좋습니다. ex) helloWorld, camelCase 


그럼 변수를 선언의 예를 들어 보겠습니다.

1
2
3
4
var a;
a = 10;
var str;
str = "baekjakka";
cs

var는 변수의 선언을 의미하고 뒤에 a 는 변수의 이름을 의미합니다. 그리고 세미콜론(;)은 마침표와 같은 역할을 하고 a = 10; 은 변수 a 에 10이란 값을 저장한 것입니다. 만약 변수에 값이 담기지 않았을 때에는 undefined 라는 값이 초기값으로 할당되어 있습니다. 


변수에 숫자도 문자도 담는게 보이는데요 변수의 타입에 대해서 알아보겠습니다.

변수의 타입에는 기본타입과 참조타입이 있는데요.

기본 타입은 변수에 저장된 값을 실제로 변수가 가지고 있는 형태이고 참조 타입은 값을 포함하는 형태입니다.

참조 타입은 하나의 값을 여러 변수에 할당 할 수 있습니다. 즉, 같은 값을 가지고 있는 경우 한 곳에서 수정하면 다른 곳에도 영향을 줄 수 있습니다.


그럼 기본타입과 참조타입의 종류를 보겠습니다.


기본타입의 종류

 종류

설명 

사용 예시 

숫자 

숫자는 기본타입입니다. 

var a = 10; 

문자 

" "(따옴표)안에 넣어야 합니다. 

var str = "baekjakka"; 

Boolean 

참(true), 거짓(false)의 값을 가집니다. 

var bool = true; 

null 

아무 값도 가지지 않습니다.  

var n = nulll; 

undefined

변수를 선언하고 아무런 값을 할당하지 않은 상태에서는 undefined값을 가집니다. null과 같습니다. 

var a;


참조타입의 종류

 종류

설명 

사용 예시 

객체(Object) 

변수와 메소드를 한곳에 모아 담는 역할을 합니다. 

var obj = new Object(); 

배열(Array) 

여러 개의 데이터를 원소로 가집니다. 

var arr = new Array(); 

함수(Function) 

실행할 코드를 미리 정의하고 호출하여 사용합니다.

function sum(a,b) {

   var c = a + b;

}

변수에 대해서 알아봤는데요. 기본타입에 대해서는 크게 어렵지 않을거라 생각됩니다. 

그리고 지금은 참조 타입에 대해서는 아직 다 이해하지 못해도 괜찮습니다.



참고서적 : JavaScript+jQuery입문+실전북

'Language > Javascript' 카테고리의 다른 글

3.javascript 조건문  (0) 2017.09.19
2.Javascript 연산자  (0) 2017.09.19
Window 객체  (0) 2017.07.20
오브젝트모델(Object Model)  (0) 2017.07.20
Javascript 위치시키기  (0) 2017.07.19

+ Recent posts