Network/WebSocket

[NodeJS] socket.io 웹 소켓 모듈 기본 사용법

범데이 2022. 1. 27. 01:12

# socket.io 모듈이란?

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

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

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

 

 

전체 샘플코드: https://github.com/Bumdayy/first_websocket


1. socket.io 모듈 설치

npm install socket.io

 

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

1) http 서버 생성

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

- 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>socket.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스크립트 로드 -->
    <!-- nodeJS상에서 "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>

 

 

 


# 실행 결과

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

 

 

- 브라우저 실행 화면


- 서버 실행 로그

반응형