[포스코x코딩온] 웹개발자 풀스택 과정 9주차 | Socket.io

구준희·2023년 8월 29일
0

[포스코x코딩온]교육

목록 보기
27/40
post-thumbnail
post-custom-banner

Socket.io란?

  • Websocket을 기반으로 실시간 웹 애플리케이션을 위한 Javacript 라이브러리이다.
    웹 클라이언트와 서버 간의 실시간 양방향 통신을 가능하게 해주는 Node.js모듈이다.

WebSocket vs Socket.io

Websocket

  • HTML5의 웹 표준 기술
  • 매우 빠르게 동작하며 통신할 대 아주 적은 데이터를 사용함
  • 이벤트를 단순히 듣고, 보내는 것만 가능함

Socket.io

  • WebSocket 프로토콜 위에 구축되었으며 HTTP 롱 폴링 또는 자동 재연결에 대한 폴백과 같은 추가 보장을 제공
  • 표준기술이 아니며, 라이브러리임
  • 소켓 연결 실패 시 fallback을 통해 다른 방식으로 알아서 해당 클라이언트와 연결을 시도함
  • 방 개념을 이용해 일부 클라이언트에게만 데이터를 전송하는 브로드캐스팅이 가능함

Socket.io 이벤트

서버측 소켓 객체의 예약 이벤트

  • connection :클라이언트가 서버에 연결되었을 때 발생, 클라이언트와의 상호작용을 초기화하거나 초기 데이터를 전달할 수 있음
  • disconnect : 클라이언트가 연결을 해제했을 때 발생
  • disconnecting : 클라이언트가 연결을 해제하려는 경우에 발생
  • error : 연결 중에 오류가 발생했을 때 발생
  • message, ping, join, leave

클라이언트측 소켓객체의 예약 이벤트

  • connect
  • connect_error
  • connect_timeout
  • reconnect

사용자 지정 이벤트

socket.emit(eventName[,...args][,ack]

이벤트 보내는 쪽

socket.emit("hello","world",(response)=>{
  console.loog(response);	// "goood"
});

이벤트 받는 쪽

socket.on("hello",(arg, callback)=>{
  console.log(arg);		//"world"
  callback("goood")

룸 관련 함수

//클라이언트를 특정 방으로 추가
socket.join("룸번호");

//클라이언트를 특정 방에서 제거
socket.leave("룸번호");

//특정 방에 속한 모든 클라이언트 들에게 특정 이벤트와 데이터를 발송
io.to("룸번호").emit('message','발송할 메세지');

//특정 방에 속한 클라이언트들에게만 특정 이벤트와 데이터를 발송
//이때 이벤트는 송신자 클라이언트를 제외한 다른 클라이언트들에게 전달
socket.broadcast.to('룸번호').emit('message','발송할메세지');

//특정 방에 속한 클라이언트들의 정보를 확인
const roomInfo = io.sockets.adapter.rooms.get('룸번호')?.size;
console.log(roomInfo); // 방에 속한 클라이언트들의 정보가 출력

📨 간단한 메세지 보내기 예제

server.js

const http = require('http');
const express = require('express');
const SocketIO = require('socket.io');

const app = express();
const PORT = 8000;

//http 서버
const server = http.createServer(app);
//socket 서버
const io = SocketIO(server);

app.set('view engine', 'ejs')
app.get('/', (req, res) =>{
    res.render('client')
})

app.get('/chat', (req,res)=>{
    res.render('chat');
})

//socket 변수명임(바꿔도됨)
io.on('connection',(socket)=>{

    socket.on('kakaoTalk',(arg,cb)=>{
        console.log(arg);
        cb(arg);
    });
    socket.on('form_message',(args)=>{
        console.log(args);
        socket.emit('backend_message',args)
    })
    socket.on('join',(res)=>{
        //채팅방을 생성하는 방법은 join("방아이디") 사용, 방이 존재하면 그 방으로 접속
        socket.join(res);
        socket.room = res;
        //broadcast는 나를 제외한 전체사용자(브라우저)에게 메세지 전달
        socket.broadcast.to(res).emit('create', '새로운 유저가 입장하였습니다.');
        //현재 접속한 채팅방에 있는 사람 수
        const roomInfo = io.sockets.adapter.rooms.get(res)?.size;
        console.log(roomInfo)
    })
    socket.on('message',(res)=>{
        //io.to(특정방아이디).emit(이벤트)
        //특정방의 전체 사용자에게 메세지 전달
        io.to(socket.room).emit('chat',res);
    })
    socket.on('leave',()=>{
        socket.leave(socket.room);
        const roomInfo = io.sockets.adapter.rooms.get(socket.room)?.size;
        console.log(roomInfo)
    })
});

//서버
server.listen(PORT, ()=>{
    console.log(`http://localhost:${PORT}`);
})

chat.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="/socket.io/socket.io.js"></script>
</head>
<body>
    <ul></ul>
    <form id="chat">
        <input type="text" id="message" placeholder="채팅내용"/><br/>
        <button>채팅</button>
        <button type="button" onclick="leave()">나가기</button>
    </form>

    <script>
        const chatForm = document.querySelector('#chat');
        const ul = document.querySelector('ul');
        //클라이언트 소켓 연결
        const socket = io()
        
        //채팅방 생성
        const chatRoom = prompt('채팅방명을 입력하세요')        
        socket.emit('join', chatRoom);

        //브라우저 접속시 이벤트
        socket.on('create',(res)=>{
            const li = document.createElement('li')
            li.textContent = res;
            ul.appendChild(li);
        })

        //폼 이벤트
        chatForm.addEventListener('submit', (e)=>{
            e.preventDefault();
            const msg = chatForm.querySelector('#message');
            socket.emit('message', msg.value);
            msg.value ='';
        })
        socket.on('chat',(res)=>{
            const li = document.createElement('li')
            li.textContent = res;
            ul.appendChild(li);
        })
        function leave(){
            console.log('leave');
            socket.emit('leave');
        }
    </script>
</body>
</html>

결과화면

profile
꾸준히합니다.
post-custom-banner

0개의 댓글