라봉이의 개발 블로그

[nodejs][socket.io] nodejs socket.io 사용기-1. socket.io란? 간단한 예제 코드 살펴보기 본문

Node.js

[nodejs][socket.io] nodejs socket.io 사용기-1. socket.io란? 간단한 예제 코드 살펴보기

Labhong 2018. 5. 13. 16:46
반응형

socket.io란??


socket.iowebsocket 프로토콜을 지원하는 네트워킹 라이브러리이다.

비동기 이벤트 방식으로 "실시간"으로 간단하게 데이터를 주고받을 수 있게 만든 라이브러리이며 정말 쉽게 만들 수 있지만 강력한 기능들로 하여금 다양한 서비스를 만들 수 있다.

서버 사이드에서는 아직 node.js에서만 가능하고 클라이언트 사이드에서는 javascript가 가능한 곳, 브라우저 심지어 스위프트나 자바 안드로이드도 가능하고 C++11도 가능한 것으로 보인다. socket.io 깃허브 주소

위에서 설명했듯 socket.io는 Websocket 프로토콜을 사용한다. 원래는 웹 브라우저에서 양방향으로 자유롭게 데이터를 교환하기 위해서 WebSocket이란 개념이 나왔고 그것을 구현할 수 있도록 만든 것이 socket.io이다.


필자는 이번에 socket.io를 사용하면서 어떤 기능을 사용했는 지 까먹지 않기 위해서 간단하게 정리하고자 한다.


먼저 서버 개발환경은 

  • OS: Windows10

  • IDE: Webstorm2017

  • express-generator로 application 생성

하였고,

클라이언트는 간단히 웹 javascript로 하겠다.


서버 디렉토리 구조

express-generator가 무엇이지 궁금하고 프로젝트를 생성하는 방법은 다음 포스트에서 확인할 수 있다. 

express-generator로 application을 생성하면 다음과 같은 구조가 생성된다. ※ (dir)는 디렉토리라는 의미

.
├── app.js
├── bin(dir)
│   └── www
├── package.json
├── public(dir)
│   ├── images(dir)
│   ├── javascripts(dir)
│   └── stylesheets
│       └── style.css
├── routes(dir)
│   ├── index.js
│   └── users.js
└── views(dir)
    ├── error.pug
    ├── index.pug
    └── layout.pug

여기서 socket.io의 이벤트를 관리할 modules라는 디렉토리를 home directory에서 추가하고 socketIOHandler.js를 추가하였다.
.
├── bin
├── modules
│   └──  socketIOHandler.js
├── public
├── routes
└── views

socketIOHandler.js의 파일에는 다음과 같이 기본 틀을 잡는다.

- modules/socketIOHandler.js
exports = module.exports = function(io) {
    io.on('connection', (socket)=> {
        console.log("SOCKETIO connection EVENT: ", socket.id, " client connected");
        // 여기서부터 socket에 대한 이벤트를 작성하면 된다.
        socket.on("event1", function(msg) {
            console.log("SOCKETIO event1 EVENT: msg: ", msg);
        })
    })
};

먼저 io.on을 이용해 "connection"이란 이벤트를 등록한다.
이 이벤트는 클라이언트가 서버에 socket.io를 통해 접속한다면 발생하는 이벤트이다. 
connection이란 이벤트는 "socket"이란 객체를 콜백함수에서 전달하는데 socket은 접속한 개별의 클라이언트로 보면 된다.(정말 중요!!)

io.on('connection')의 콜백함수 안에서 socket, 즉 클라이언트에게 발생하는 이벤트들을 등록할 수 있다.

그 후에 socket에 대한 이벤트를 on을 통해 이벤트를 받을 준비를 하고 emit을 통해 이벤트를 접속한 클라이언트로 발송한다.

위의 코드는 event1 이란 이벤트를 클라이언트가 emit할 때를 대비해 받아놓을 핸들러를 만든 것이다.
간단하게 클라이언트가 event1을 emit할 때 전송한 msg를 콘솔창에 찍는 함수를 등록했다.

(※ socketIOHandler는 코드를 보듯이 외부에서 socketIO에 대한 라이브러리를 io라는 변수로 받아온다. 이렇게 구조를 잡은 이유는 이벤트 핸들러가 많아질수록 한 파일에 관리하기 어려우므로 분리해서 관리하기 위함이다.)

그리고 bin/www에서 socketIOHandler 모듈을 불러온다.

- bin/www
const app = require('../app');
const debug = require('debug')('socketiotest:server');
const http = require('http');

const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

const server = http.createServer(app);
const io = require('socket.io')(server);        // socket.io 모듈을 사용 및 create 한 http 서버 전달

// socket.io의 이벤트 핸들러 등록 및 위의 socket.io 라이브러리를 socketIOHandler에 전달
const socketIOHandler = require('../routes/socketIO')(io);

....(뒤의 코드 생략)

주의할 점은 반드시 http 서버를 createServer한 후에 socket.io에 전달해야하는 것이다.

이제 클라이언트의 코드를 간단히 살펴보자.
... (위의 코드 생략)
<head>
  <script src="/socket.io/socket.io.js"></script>
  <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
  <script>
      var socket = io(); // TIP: io() with no args does auto-discovery
      socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
          socket.emit('event1', 'tobi');
      });
  </script>
</head>
<body>
  ... (코드 생략)
</body>
... (코드 생략)

socket.io 클라이언트 스크립트인 <script src="/socket.io/socket.io.js" />는 socket.io를 잘 설치했고 위에서처럼 http server를 socket.io로 랩핑했다면 자동으로 클라이언트가 서버에 요청하고 받아서 사용할 것이니 저렇게 사용하면 된다.

그리고 접속할 서버를 지정해줘야하지만 var socket = io(); 처럼 그냥 생성하면 디폴트로 페이지를 전달해준 서버와 자동으로 연결한다.

그 후에 socket.on을 이용해 connect가 되었다면 그 다음 이벤트를 작성할 수 있다.

위의 코드는 connect가 되자마자 바로 event1이란 이벤트를 emit하고 그 데이터로 'tobi'란 문자열을 날린다.
따라서 서버는 msg로 tobi를 받게 되는 것이다.

서버의 콘솔 창을 보면 다음과 같은 문자열을 볼 수 있다.
SOCKETIO event1 EVENT: msg:  tobi

이렇듯 socket.io를 사용하면 매우 쉽게 실시간으로 데이터를 전송할 수가 있다.

다음 포스트에선 socket.io를 좀 더 효율적으로 사용한 경험을 적도록 하겠습니다.


반응형
Comments