반응형
2차 프로젝트에서 사용했던 Socket 기술을 정리해본다
TCP / IP
- 컴퓨터 네트워크에서 데이터 통신을 위한 프로토콜 스택
TCP ( Transmission Control Protocol )
TCP 는 데이터를 신뢰성 있게 전송하기 위한 프로토콜
네트워크 인터페이스 계층
- 물리 계층과 데이터 링크 계층에 해당
- 데이터를 전기 신호로 변환하거나 광 신호로 변환하여 전송
- MAC ( Media Access Control ) 주소를 관리
인터넷 계층
- 네트워크 계층에 해당
- 데이터 패킷의 라우팅과 논리적인 주소 지정을 담당
- IP 프로토콜이 이 계층에서 작동하며, 패킷의 출발지와 목적지 IP 주소를 사용하여 라우팅 수행
전송 계층
- 신뢰성과 흐름 제어를 관리
- TCP와 UDP가 이 계층에서 작동
응용 계층
- 최종 사용자에게 서비스를 제공하기 위한 응용프로그램과 사용자 인터페이스가 이 계층에 위치
- 다양한 프로토콜을 포함하며, HTTP, FTP, SMTP, POP3, IMAP, DNS 등의 프로토콜이 이 계층에서 동작
Socket
- 서버와 클라이언트를 연결해주는 도구로써 인터페이스 역할
- 서버 : 클라이언트 소켓의 연결 요청을 대기하고, 연결 요청이 오면 클라이언트 소켓을 생성해 통신을 가능하게 하는 것
- 클라이언트 : 실제 데이터 송수신이 일어나는 곳
- 소켓은 프로토콜, IP 주소, 포트 넘버로 정의된다.
- TCP 와 UDP 프로토콜을 사용하여 데이터를 전송
소켓 프로그래밍 흐름
- 서버(Server)
- socket() : Socket 생성 함수
- bind() : ip와 port 번호 설정 함수
- listen() : 클라이언트의 요청에 수신 대기열을 만드는 함수
- accept() : 클라이언트와의 연결을 기다리는 함수
- 클라이언트(client)
- socket() : 소켓을 여는 함수
- connect() : 통신할 서버의 설정된 ip와 port 번호에 통신 을 시도하는 함수
통신 시도 시, 서버가 accept()함수를 이용해 클라이언트의 socket descriptor를 반환
이를 통해 클라이언트와 서버가 서로 read() write()를 반 복하며 통신
사용자가 화면을 새로고침 하지 않아도 데이터를 갱신해야 할 때 소켓을 사용하게된다
일반적인 웹 데이터 송수신
- HTTP 프로토콜 : 요청을 보내야지만 서버가 응답 ( 단방향 통신 )
웹 소켓
- 화면 새로고침 없이 실시간성을 필요로 하는 앱에서 사용 ( 양방향 통신 )
- 실시간 네트워킹 유리
- 브로드캐스팅 ( 여러 컴퓨터에 데이터를 일괄 전송 ) 지원
WebSocket 이란
- 양방향 소통을 위한 프로토콜
- HTML5 웹 표준 기술
- 빠르게 작동하며 통신할 때 아주 적은 데이터를 이용
- 이벤트를 단순히 듣고, 보내는 것만 가능
- Handshake : 클라이언트가 서버로 웹소켓 연결을 요청할 때, 서버와 클라이언트 측에서는
브라우저의 WebSocket 객체를 사용하여 웹소켓 연결을 생성하고 관리
WebSocket 이벤트
- open: 웹소켓 연결이 성공적으로 열렸을 때 발생
- message: 웹소켓을 통해 데이터를 주고받을 때 발생
- error: 웹소켓 연결 중 오류가 발생했을 때 발생. 연결 실패, 통신 오류 등이 해당
- close: 웹소켓 연결이 종료되었을 때 발생
ws 모듈 이벤트
- connection: 클라이언트가 웹소켓 서버에 연결되었을 때 발생. 이 이벤트 의 콜백 함수는 새로운 클라이언트 연결마다 실행
- message: 클라이언트로부터 메시지를 받았을 때 발생
- error: 웹소켓 연결 중 오류가 발생했을 때 발생
- close: 클라이언트와의 연결이 종료되었을 때 발생
server.js
const ws = require('ws');
const express = require('express');
const app = express();
const PORT = 8000;
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('client');
});
const server = app.listen(PORT, () => {
console.log(`http://localhost:${PORT}`);
});
const wsServer = new ws.Server({ server }); // 웹 소켓 서버 접속
const sockets = []; // 클라이언트들을 저장할 배열
wsServer.on('connection', (socket) => {
console.log('클라이언트가 연결되었습니다.');
sockets.push(socket);
// 클라이언트의 메세지 수신
socket.on('message', (msg) => {
console.log(`클라이언트로부터 받은 메세지 : ${msg}`);
// 웹소켓 서버에 접속한 모든 클라이언트에게 메세지 전송
// 브로드캐스팅(여러 컴퓨터에게 데이터를 전송)
sockets.forEach((socket) => {
socket.send(`${msg}`);
});
});
socket.on('error', (err) => {
console.log('오류가 발생했습니다.', err);
});
socket.on('close', () => {
console.log('클라이언트와 연결이 종료되었습니다.');
});
});
client.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Web Socket 채팅</title>
</head>
<body>
<h1>채팅</h1>
<!-- 채팅 내역 -->
<ul></ul>
<!-- 채팅 인풋 -->
<form id="chat">
이름<input type="text" id="name" class="name" /> <br />
내용<input type="text" id="message" class="message" /> <br />
<button>전송</button>
</form>
<script>
const socket = new WebSocket('ws://localhost:8000');
const chatForm = document.querySelector('#chat'); // 폼 가져오기
const ul = document.querySelector('ul'); // 채팅 내역을 보여주기 위한 ul 요소
console.log(socket);
socket.addEventListener('open', (event) => {
console.log('서버 연결 완료');
});
socket.addEventListener('close', (event) => {
console.log('서버 연결 종료');
});
socket.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log(data);
const { msg, name } = data;
const li = document.createElement('li');
li.textContent = `${name}님 - ${msg}`;
ul.appendChild(li);
});
socket.addEventListener('error', (event) => {
console.log('오류 발생 : ', event.console.error);
});
// 인풋에 입력한 정보를 바탕으로 메세지 데이터 생성
chatForm.addEventListener('submit', (event) => {
event.preventDefault();
const msg = chatForm.querySelector('#message');
const name = chatForm.querySelector('#name');
data = { msg: msg.value, name: name.value };
console.log('보내려는 메세지 데이터: ', data);
// 웹 소켓 서버가 데이터를 쉽게 처리할 수 있도록
// JSON 형식의 텍스트 데이터로 변환하여 웹서버로 전송
socket.send(JSON.stringify(data));
msg.value = '';
name.value = '';
});
</script>
</body>
</html>
Socket.IO
- 클라이언트와 서버 간의 짧은 지연 시간, 양방향 및 이벤트 기반 통신을 실시간 으로 가능하게 하는 라이브러리
- WebSocket 프로토콜 위에서 구축되었으며 통신 과정을 단순화하고 개선하 기 위한 추가 기능을 제공
- 특징
- 이벤트 기반 ( 사용자가 임의로 설정이 가능하다 )
- 자동 재연결
server.js 에서의 ' connection ' 이벤트 추가
// io.on(): socket 관련 통신 작업을 처리
io.on('connection', (socket) => {
// connection 이벤트는 클라이언트가 접속했을 때 발생
// 콜백 함수 인자로 socket 객체를 제공
console.log('서버 연결', socket);
});
chat.ejs 에서의 ' connect ' 이벤트 추가
let socket = io.connect(); // 소켓 사용을 위한 객체 생성
socket.on('connect', () => {
console.log('클라이언트 연결 완료 : ', socket);
});
SocketID ?
- 소켓의 고유 ID ( 브라우저 탭 단위 )
'hello' 라는 이벤트를 만들어 위의 코드를 작성하면 아래와 같은 결과를 가질 수 있다.
한마디로 소켓의 동작과정은
클라이언트의 요청 > 소켓서버가 요청을 받고 > 다시 클라이언트로 해당 메세지를 보냄 > 서버에서 보내온 메세지 출력 순이다
반응형
'SeSAC' 카테고리의 다른 글
[새싹X코딩온] 풀스택 2차 프로젝트 회고록 (1) | 2023.11.14 |
---|---|
[새싹X코딩온] 풀스택 1차 프로젝트 회고록 (2) | 2023.09.24 |
[새싹X코딩온] 풀스택 5주차 회고록 - 1 | 동기/비동기 (0) | 2023.08.19 |
[새싹X코딩온] 풀스택 4주차 회고록 - 2 | Node.js, javascript 심화 (0) | 2023.08.13 |
[새싹X코딩온] 풀스택 4주차 회고록 - 1 | 클라이언트와 서버 (0) | 2023.08.12 |