라봉이의 개발 블로그

[nodejs][socket.io] nodejs socket.io 사용기-2. room 사용, 현재 연결된 socket 찾기, disconnect 이벤트 본문

Node.js

[nodejs][socket.io] nodejs socket.io 사용기-2. room 사용, 현재 연결된 socket 찾기, disconnect 이벤트

Labhong 2018. 5. 13. 18:14
반응형

이전 포스트: [Node.js] - [nodejs][socket.IO] 노드js 소켓 IO 사용기-1. socket.io란? 간단한 예제 코드 살펴보기


이전에는 socket.io를 간단히 사용하는 법을 살펴 보았다.


이번 포스트는 socket.io를 좀 더 유용하게 만들었던 함수들을 어떻게 썼는 지 정리해보고자 한다.



현재 연결된 소켓을 id로 찾기


현재 연결된 소켓 중에서 socket.id를 이용해 소켓 객체를 가지고 오고 싶을 때 


io.socketsnamespace를 리턴한다.

namespace란 기본적으로 다른 end points나 경로를 지정하는 것을 의미한다고 정식 docs에 나와있다. 

사용해보지 않아서 잘 모르겠지만 소켓들은 namespace를 통해 구분될 수 있고 이벤트를 달리할 수 있는 것으로 이해했다.


하지만 일단 const io = require('socket.io')(server)를 통해 생성된 socket들은 default namespace 안에 관리되어있으므로 나중에 namespace에 대해 정리하고자 한다.


여하튼 io.sockets는 default namespace를 리턴하고 namespace의 프로퍼티로써 connected가 존재한다.


connected는 socket.id를 key 값으로 가지고 이 namespace에 연결(connect)된 객체들의 해쉬이다.


간단히 io.sockets.connected[<특정 socket.id>]를 통해 특정 socket을 리턴한다는 의미이다.


다 무시하고 현재 연결된 특정 socket에만 이벤트를 emit할 경우가 생기면 다음과 같이 작성하면 된다.

let clientSocket = io.sockets.connected[user.socketId];
clientSocket.emit("event1", data);



Socket 자체에 프로퍼티를 추가하기


socket이 connection이 되면 콜백함수로 socket 객체를 받는다.

socket 객체property를 추가해 나중에 필요한 데이터를 사용할 수가 있다.


예를 들어 socket이 연결 된 후 nickname을 서버에서 할당 받았고 나중에 클라이언트가 emit한 이벤트에 닉네임을 사용할 일이 생겼다면 다음과 같이 사용할 수 있다.


server 코드

io.on('connection', (socket)=> {
        console.log("SOCKETIO connection EVENT: ", socket.id, " client connected");

        let nickname = getNickName();   // 고유 닉네임 할당 받음
        socket.nickname = nickname;     // nickname 프로퍼티를 동적으로 생성

        socket.emit("getNickname", socket.nickname);    // socket의 nickname 프로퍼티에 접근
    })


client 코드

<script>
    var socket = io(); 
    socket.on('connect', function () {
        socket.on("getNickname", function(msg) {	// getNickname 이벤트 핸들러 등록
            console.log("Nickname: ", msg);		// 받은 nickname을 콘솔창에 띄움
        })
    });
</script>



Room이란?


Room이란 말 그대로을 의미한다. 각 socket들은 참여할 수 있고 탈퇴할 수 있는 임의의 room을 정의할 수 있는데 이 room이라는 것은 채팅방을 빗대어 생각하면 좀 이해하기 편리할 것이다.


socket은 room에 대한 joinleave를 할 수 있다.

join이란 room에 참여하는 것이고, leave는 room에 탈퇴하는 것이다.


join 예제

io.on('connection', function(socket) {

    socket.join('room1');

}

leave 예제

leave함수는 위와 마찬가지로 socket.leave('room1');과 같이 작성하면 된다.


room을 사용하는 이유는 room에 참여한 socket 들에 대해서 한번에 이벤트를 emit할 수 있다는 점이다. 


예를 들어 채팅방에 메세지가 들어온다면 그 채팅방에 속한 소켓들에게만 데이터를 전달할 수 있다.


server 코드

io.on('connection', (socket)=> {
        console.log("SOCKETIO connection EVENT: ", socket.id, " client connected");

        socket.on('joinRoom', function(msg) {     // joinRoom을 클라이언트가 emit 했을 시
            let roomName = msg;
            socket.join(roomName);    // 클라이언트를 msg에 적힌 room으로 참여 시킴
        });

        socket.on('chatting', function(msg) {       // 클라이언트가 채팅 내용을 보냈을 시
            // 전달한 roomName에 존재하는 소켓 전부에게 broadcast라는 이벤트 emit
            io.to(msg.roomName).emit('broadcast', msg.msg); 
        })
    })


client 코드

<head>
  <script src="/socket.io/socket.io.js"></script>
  <script>
      $(function () {
          var socket = io();
          socket.emit('joinRoom', "room1");
          $('form').submit(function(){
              socket.emit('chatting', {
                  roomName: "room1",
                  msg: $('#m').val()
              });
              $('#m').val('');
              return false;
          });
          socket.on('broadcast', function(msg){
              $('#messages').append($('<li>').text(msg));
          });
      });
  </script>
</head>
<body>
  <ul id="messages"></ul>
  <form action="">
    <input id="m" autocomplete="off" /><button>Send</button>
  </form>
</body>



disconnect 이벤트


disconnect 이벤트는 socket, 즉 클라이언트와 서버와의 연결이 끊겼을 때 발생하는 이벤트이다. 

socket과의 연결이 끊겼을 때의 핸들러가 필요하다면 disconnect 이벤트를 이용하도록 한다.


물론 io.on('connection', function(socket) { ... }); 에서의 콜백함수 안에 작성해야한다.


disconnect 예제

socket.on('disconnect', function() {

     console.log("SOCKETIO disconnect EVENT: ", socket.id, " client disconnect");

     // 여기서부터 필요한 내용을 작성하면 된다.

}


반응형
Comments