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

+ Recent posts