# 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>
# 실행 결과
서버 구동 후, 브라우저에서 접속하여 메시지를 보내고 연결종료 버튼까지 누른 상태의 로그이다.
- 브라우저 실행 화면
- 서버 실행 화면
'개발(Development) > JS(자바스크립트)' 카테고리의 다른 글
[자바스크립트] 텍스트 클립보드 복사(copy)/붙여넣기 기능 구현 방법 (0) | 2021.07.08 |
---|---|
[자바스크립트] HTML엘리먼트 생성, 추가, 삭제, 속성/텍스트/내부html 설정 방법 (0) | 2021.07.07 |
[자바스크립트] HTML 엘리먼트(태그/노드) 선택/취득 방법 (0) | 2021.07.04 |
Node.js: Web Socket 통신 - ws모듈 사용 방법 (0) | 2021.07.02 |
Javascript: URI, URL, QueryString과 인코딩/디코딩 정리 (0) | 2021.07.02 |
댓글