본문 바로가기
개발(Development)/JS(자바스크립트)

[node.js] Socket.IO 웹 소켓 모듈 기본 사용 방법

by 카레유 2021. 7. 6.

# Socket.IO 모듈이란?

socket.io는 소켓 구현시 필요한 다양한 편의기능을 제공하는 모듈로,

웹소켓이 지원되지 않는 브라우저에서도 작동하도록 내부적으로 구현해 준다.

(ws 프로토콜이 지원되지 않는 경우, http 프로토콜로 반복적으로 서버와 통신하는 polling 방식을 이용한다.)

 

웹 소켓 자체 및 ws모듈에 대해서는 아래 글 참고! 전체 샘플코드는 글 하단에 첨부!

Node.js: Web Socket 통신 - ws모듈 사용 방법


#1 socket.io 모듈 설치

-  npm install socket.io 


#2 서버 측 socket.io 설정 작업

1. http 서버 생성

const app = require("express")();
const server = app.listen(30001, ()=>{ ... 코드 ... });

- express 등을 활용해 http 서버 생성 및 구동

 

2. socket.io 객체 생성 및 구동

const io = socketIO(server, {path: "/socket.io"});

 

- 첫번째 매개변수: 연결할 http서버를 설정

- 두번째 매개변수: 객체{키: 값, ... } 형태로 각종 옵션을 설정한다

  * path옵션: 이 경로를 통해 통신을 수행하며, 생략시 디폴트 값은 /socket.io 로 지정된다.

 

3. 주요 이벤트 처리

io.connect('connect', (socket)=>{
    socket.on('disconnect', (reason)=>{...코드...});
    socket.on('error', (error)=>{...코드...});
    socket.on('사용자정의이벤트', (data)=>{...코드...});
});

 

- connect 이벤트를 제외하곤, 콜백함수의 매개변수로 들어온 socket객체에 이벤트 처리를 해주는 점에 주의하자!

1) connect: 연결 성공

2) disconnect: 연결 종료

3) error: 에러 발생

4) 그외 : 사용자 정의 이벤트

 

4. 데이터 전송 to 클라이언트: 사용자 정의 이벤트 발생

socket.emit('이벤트 이름', '클라이언트에게 전송할 데이터 내용');

- emit()메서드를 통해 클라이언트에게 "데이터"를 보낼 수 있다.

- 클라이언트에서는 "이벤트이름"으로 데이터를 받아 처리할 수 있다.


#3 클라이언트 측 socket.io 설정 작업

1. socket.io 모듈 스크립트 로드

<script src="/socket.io/socket.io.js"></script>

- socket.io모듈은 내부적으로 "루트/socket.io" 경로socket.io.js 파일을 자동으로 등록해둔다.

- 결과적으로 위 코드는 socket.io모듈이 자동으로 생성해둔 http://127.0.0.1:30001/socket.io/socket.io.js 에 접근하여 JS 스크립트를 불러오게 된다.

- 단, node.js 상에서 "socket.io 객체 생성시 설정한 path" 경로로 접근해야 한다.(생략시 디폴트가 /socket.io로 지정된다)

 

 

2. 서버 socket접속용 객체 생성 및 연결

const socket = io.connect("http://127.0.0.1:30001", {path: "/socket.io", transports: ['websocket']});

- 연결할 서버 경로 및 옵션을 설정해준다.

1) path 옵션

: 이 경로를 통해 각종 통신을 수행하며, node.js상에서 설정한 path와 동일하게 지정해야한다.

2) transports 옵션

: socket.io는 처음에 polling 연결을 시도하고, 웹소켓이 지원되는 브라우저인 경우, ws통신으로 변경한다.

: 처음부터 ws 통신하고자 경우, transports 옵션 값을 ['websocket']으로 추가 설정해주면 된다.

 

3. 이벤트 처리(연결/종료/에러/데이터 수신 등)

socket.on('connect', ()=>{... 코드 ...});
socket.on('disconnect', (reason)=>{... 코드 ...});
socket.on('error', (error)=>{... 코드 ...});
socket.on('사용자정의이벤트', (data)=>{... 코드 ...});

1) connect: 연결 성공

2) disconnect: 연결 종료

3) error: 에러 발생

4) 그외 : 사용자 정의 이벤트 - 개발자가 서버에 데이터 전송시 '이름표'를 달고 보내는 이벤트다.

 

4. 데이터 전송 to 클라이언트: 사용자 정의 이벤트 발생

socket.emit('이벤트 이름', '서버에게 보낼 데이터 내용');

 

- emit()메서드를 통해 서버에게 "데이터"를 보낼 수 있다.

- 서버에서는 "이벤트이름"으로 데이터를 받아 처리할 수 있다.


# 전체 샘플 소스코드

- 서버측 소스코드

// ################## HTTP 서버(express) 생성 부분
// # express모듈 객체 생성
const express = require('express');
const app = express();

// # 정적 파일 경로 설정
const path = require("path");
app.use(express.static(path.join(__dirname, '/'))); 

// # 라우팅 처리
app.use("/", (req, res)=>{
    res.sendFile(path.join(__dirname, 'index.html'));
})

// # HTTP 서버 구동(port: 30001)
const server = app.listen(30001, ()=>{
    console.log("Server is Listening at 30001");
})


// ################## socket.io 모듈 사용 부분
// # socket.io 모듈 추출
const socketIO = require("socket.io");

// # socket.io 객체 생성: 1) http서버 연결, 2) path 설정(생략시 디폴트: /socket.io)
const io = socketIO(server, {path: "/socket.io"});

// # socket.io 객체의 이벤트 리스터 설정
// 1) 연결 성공 이벤트: "socket.io 객체"로 "connect" 이벤트 처리
io.on('connect', (socket)=>{ 
    const ip = socket.request.headers['x-forwarded-for'] || socket.request.connection.remoteAddress;
    console.log(`클라이언트 연결 성공 - 클라이언트IP: ${ip}, 소켓ID: ${socket.id}`);

    // 2) 연결 종료 이벤트: "매개변수로 들어온 socket"으로 처리해야 함 주의!
    socket.on('disconnect', (reason)=>{
        console.log(reason);
        console.log(`연결 종료 - 클라이언트IP: ${ip}, 소켓ID: ${socket.id}`)
    });

    // 3) 에러 발생 이벤트: "매개변수로 들어온 socket"으로 처리해야 함 주의!
    socket.on('error', (error)=>{
        console.log(`에러 발생: ${error}`);
    });

    // 4) 클라이언트에서 보낸 이벤트 처리: 클라이언트에서 "client_msg" 이름으로 보낸 데이터 수신
    socket.on('client_msg', (data)=>{
        console.log(`클라이언트에서 보낸 메시지 수신: ${data}`);

        // # 클라이언트에게 "server_msg" 이름으로 데이터 전송
        socket.emit('server_msg', `[${socket.id}]소켓 서버에서 보낸 메세지입니다.`);
    });
});

 

- 클라이언트측(브라우저) 소스코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sokcet.io 테스트</title>
</head>

<body>
    <h1>socket.io 테스트</h1>
    
    <input type="text" id="input_msg">
    <button id="btn_send">메세지 전송</button>

    <button id="btn_disconnect">연결 종료</button>
</body>

<!-- socket.io 모듈이 제공하는 js스크립트 로드 -->
<!-- node.js 상에서 "socket.io 객체 생성시 설정한 path"/socket.io.js로 접근해야 함 -->
<script src="/socket.io/socket.io.js"></script>
<script>

    // 서버 socket 접속용 객체 생성 및 연결
    const socket = io.connect("http://127.0.0.1:30001", {path: "/socket.io", transports: ['websocket']});

    // # 연결(connect) 이벤트 처리
    socket.on('connect', ()=>{
        console.log('연결 성공');
    });
    
    // # 연결 해제(disconnect) 이벤트 처리
    socket.on('disconnect', (reason)=>{
        console.log(reason);
        console.log('연결 종료');
    });

    // # 에러 발생(error) 이벤트 처리
    socket.on('error', (error)=>{
        console.log(`에러 발생: ${error}`);
    });

    // # 서버가 보낸 "사용자정의 이벤트" 처리: 매개변수로 들어온 데이터를 받아서 처리한다.
    socket.on('server_msg', (data)=>{
        console.log(`서버에게 받은 메시지: ${data}`);
    });

    
    // # "메시지전송" 버튼 클릭 이벤트 처리
    document.getElementById('btn_send').onclick = function(){
        // 1) input 텍스트 취득
        const msg = document.getElementById('input_msg').value;
        
        // 2) 서버 소켓에 "client_msg" 이름으로 데이터 전송
        socket.emit('client_msg', msg);
    }
    
    // # "연결종료" 버튼 클릭 이벤트 처리
    document.getElementById('btn_disconnect').onclick = function(){
        // 연결 종료 처리
        socket.disconnect();
    }
</script>

</html>

# 실행 결과

서버 구동 후, 브라우저에서 접속하여 메시지를 보내고 연결종료 버튼까지 누른 상태의 로그이다.

- 브라우저 실행 화면

 

- 서버 실행 화면

 

 

 

댓글