Socket.io사용해보기

백승일·2020년 11월 11일
1

TodayILearn

목록 보기
5/9

웹소켓을 조금씩 공부하다보니 조금 더 많은 브라우저에서 사용할 수 있는 webSocket.io에 대해서 공부하고 싶어졌다. 조금 더 공부하면 카톡같은 채팅 어플을 만들 수 있을 지 않을까. 일단 지금은 이 지식이 고파졌다.

Socket.io시작

일단 이것도 그냥 webSocket처럼 실시간 통신을 지원하기 위한 도구임에는 틀림없다. 다른점은 브라우저에서 지원하는 최적의 방법으로 알아서 동작하는 점 정도. 그러면 일단 이 친구의 속을 뒤집어 까보자.

서버와 클라이언트간의 실시간 소통이라하면 결국 주고 받는 애가 양쪽에 다 있어야한다는 말이다. 서버에서는 "npm i socktet.io"를 이용하여 설치하고 클라이언트는

<script src="/socket.io/socket.io.js"></script>
const socket = io()

를 이용하여 io를 사용할 수 있다. 먼저 express를 이용하여 서버를 열자

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

io.on('connection',socket=>{
	socket.on()
})

http.listen(3000, () => {
  console.log('Connect at 3000');
});

서버에 클라이언트가 접속하면 connection이벤트가 발생하고 이 이벤트를 서버에서는 io.on('connection',sockect=>{}) 이렇게 받는데, 이때 콜백함수의 인자인 socket은 개별 클라이언트와 통신하기 위한 객체이다. io는 전체 클라이언트를 위한 객체이다.

io와 socket의 채팅 메소드로는 아래와 같다.
Method Description
io.emit 접속된 모든 클라이언트에게 메시지를 전송한다.
socket.emit 메시지를 전송한 클라이언트에게만 메시지를 전송한다.
socket.broadcast.emit 메시지를 전송한 클라이언트를 제외한 모든 클라이언트에게 전송
io.to(id).emit 특정 클라에게만 메시지를 전송한다. id는 socket 객체의 id 속성값이다.
Parameter Description
event name 이벤트 명(string)
msg 송신 메시지(string or object)

일단 on이 이벤트를 받음, emit이 이벤트를 보냄이라 생각해보자. 서버측에서는 클라이언트의 이름을 받고, 채팅을 받으면 보낸 클라이언트를 제외한 모든 클라에 메시지를 보내고 클라이언트의 접속이 끊겼을 때, 모든 채팅에 떠난 아이디를 알려주는 역할을 해보려한다.

io.on('connection',socket=>{
// 소켓이 궁금하니까 콘솔에 찍어보고
  console.log(socket);
// login이라는 이벤트가 오면 socket에 닉네임과 고유아이디를 저장한다.
  socket.on('login',data=>{
    socket.nickName = data.nickName;
    socket.userId = data.userId;
    // 모든 클라에게 메시지 전송
    io.emit('joinEvent',"누군가 접속했다");
  });
// chat이라는 이벤트가 오면 메시지를 정리하고 보낸 사람을 동봉하여 다른 클라에 보내준다.
  socket.on('chat',data=>{
    console.log(data);
    const msgData = {
      send:socket.nickName,
      msg:data.msg
    };
    // 송신자를 제외한 나머지에게 메시지 보내기
    socket.broadcast.emit('chat',msgData)
  })
// 누군가 떠나면 저장된 닉넴을 보내준다. 
  socket.on('disconnect',()=>{
    io.emit('disconnected',socket.nickName);
  })
})

이렇게 서버측 코드를 작성해주고 이제 클라이언트에서 코드를 써보자.

//socket.io를 가져와주고
<script src="/socket.io/socket.io.js"></script>
<script>
	const socket = io();
// 서버에 로그인 정보 보내기
	socket.emit("login",{
    	name:"인풋태그 값",
      	userId:"인풋태그 값"
    })
// 서버에서 login으로 송신하면 채팅창에 로그인 이력보여주기
	socket.on("login",data=>{
    	채팅창.innerHTML(`<p>%{data}가 접속했당</p>`)
    })
// 받은 채팅을 채팅창에 보여주기
	socket.on("chat",data=>{
    	채팅창.innerHTML(`<p>%{data.send}: ${data.msg}</p>`)
    })
// 보내기 버튼 클릭하면 보낸 메시지는 나한테 안오니까 내가 직접 넣기
	보내기버튼.addEventListener("click",e=>{
      //보낸 채팅 DOM에 추가하고
      채팅창.innerHTML(`<p>${입력한채팅input.value}</p>`)
      // 서버로 보내고
      socket.emit("chat",{msg:입력한채팅input.value})
    })
// 누군가 나가면 알려주기
	socket.on("disconnected",data=>{
		채팅창.innerHTML(`<p>${datga}가 채팅방을 나갔습니다.</p>`)
    })
</script>

이렇게 간단한 채팅웹을 만들어 보았다. 지금은 하나의 채팅방에서 채팅을 하지만 socket.io에는 방을 나눌 수 있는 namespace기능과 namespace안에서도 다시 방을 나누는 room기능이 있다. 메이플스토리로 생각해보자면, 하나의 서버(베라 등)안에 여러 채널(namespace)가 있고 그 안에 map(room)이 있는것이다. 때문에 맵에서 전체 채팅으로 쳐도 해당 맵에 있는 사람들만 볼 수 있듯이 room도 해당 room에 있는 클라 끼리만 대화가 가능하다.

profile
뉴비 개발자

0개의 댓글