빠르게 훝어보는 node.js
#10 - Socket.IO (2/4)
조대협 (http://bcho.tistory.com)
Socket.IO APIs
Socket.IO는 이밖에도 다양한 이벤트를 전달할 수 있는 API를 제공하는데, 이에 대해서 살펴보자.
여기서 사용하는 socket이라는 객체는
io.sockets.on('connection',function(socket){
에 의해서 callback function에 의해서 전달된 인자임을 미리 명시해둔다.
<!--[if !supportLists]-->1. <!--[endif]-->이벤트 보내기 받기
먼저 소켓으로 또는부터 이벤트를 보내고 받는 방법부터 알아보자.앞에 예제에서도 봤지만 가장 간단한 방법은
<!--[if !supportLists]--> * <!--[endif]-->이벤트 보내기 socket.emit('이벤트명',{메세지});
현재 연결되어 있는 클라이언트 소켓에 “이벤트명”으로 “{메시지}” 데이터로 이벤트를 보낸다.
<!--[if !supportLists]--> * <!--[endif]-->이벤트 받기 socket.on('이벤트명',function(data){ });
현재 연결되어 있는 클라이언트 소켓으로부터 들어오는 “이벤트명”이벤트에 대해서 두번째 인자로 정의된 callback function에 의해서 이벤트에 대한 처리를 한다. 이때 이벤트 메시지는 callback function의 인자인 “data”를 통해서 전달된다.
하나의 클라이언트가 아니라 다수의 다른 클라이언트나 또는 다른 클라이언트에 이벤트를 어떻게 보내는지 알아보자
<!--[if !supportLists]--> * 나를 제외한 다른 클라이언트들에게 이벤트 보내기 socket.broadcast.emit('이벤트명',{메세지});
socket에 대해서 broadcast를 하면, 나를 제외한 다른 소켓 클라이언트들에게 이벤트를 보낼 수 있다.
<!--[if !supportLists]--> * <!--[endif]-->나를 포함한 모든 클라이언트들에게 이벤트 보내기io.sockets.emit('이벤트명',function(data){ });
개별 클라이언트 소켓을 대표하는 객체가 socket이라면, 전체 연결된 socket들을 대표하는 객체는io.sockets이다. 여기서는 io.sockets.emit를 사용했는데, 이는 전체 연결된 클라이언트 소켓에 대해서 이벤트를 보내도록 한 것이다.
내 소켓이 아닌 다른 특정 소켓에게 이벤트를 보내는 방법이 있는데,
<!--[if !supportLists]--> * <!--[endif]-->io.sockets(socket_id).emit('이벤트명',function(data){ });
를 사용하면 된다. 이때 socket_id는 socket.id 값으로 각 클라이언트 소켓은 id라는 property를 가지고 있고, 이는 각 소켓을 구별해주는 식별자가 된다. 그나중에 예제에서 설명하겠지만, 채팅 귓속말과 같이 특정 소켓으로 메시지를 보내려면, 메시지를 전달하는 대상이 되는 소켓의 id값을 알아서 위의 io.socket(socket_id)로 이벤트를 전달해야 한다.
<!--[if !supportLists]-->2. <!--[endif]-->소켓에 데이터 바인딩
각 소켓에는 소켓에 연관된 데이터를 set 메서드를 이용해서 binding하고, get을 이용해서 binding 된 데이터를 꺼낼 수 있다.
<!--[if !supportLists]--> * socket.set(‘key’, ‘value’,function() {});
<!--[if !supportLists]--> * socket.get(‘key’, function(err,value) {});
<!--[if !supportLists]--> * socket.del(‘key’, function(err,value) {});
값으 저장할때는 set을 이용하여 socket에 key값을 키로 사용하여 value라는 데이터를 저장한다. 값을 읽어올 때는 get을 이용하여 socket에 저장된 key이름으로 저장된 값을 value를 통해서 리턴한다.그리고 해당값을 삭제하고자 할때는 del을 이용하여 socket에 key이름으로 저장된 값을 삭제한다.
socket도 객체이기 때문에 Object의 property를 사용해도 되는데, 예를 들어 socket.key = value 왜 굳이 set/get을 사용할까? socket.io의 set/get 내부 구현을 뜯어보면 실제로는 Object의 property를 사용한다. 단 socket.io의 store를 Redis로 지정하게 되면, 이 set/get은 값을 내부 Object property에 저장하지 않고, Redis에 저장하게 되서, 이 값들은 클러스터 노드 (다른 노드간)에서도 접근이 가능해진다.
<!--[if !supportLists]-->3. <!--[endif]-->Room 처리 (그룹)
socket.io는 소켓들을 그룹핑하는 채널과 같은 개념인 ‘room’이라는 개념을 지원한다. 채팅 프로그램의 대화방과 같은 개념이다. Room을 사용하게 되면 broadcast를 하더라도 같은 room안에 있는 클라이언트에게만 이벤트가 전송된다.
<!--[if !supportLists]--> * socket.join(‘roon name’)
<!--[if !supportLists]--> * socket.leave(‘roon name’)
소켓을 특정 room에 binding하는 방법은 join을 이용하면 해당 소켓은 그 room에 binding이 되고, leave를 하면 그 room에서부터 나오게 된다.
특정 room에 있는 socket에게 이벤트를 보내는 것은 앞에 설명한 똑같이 socket.emit을 사용하면 되는데, broadcast를 하거나 room안에 있는 전체 클라이언트 소켓에게 이벤트를 보낼때는 아래와 같이 room을 명시해주면 된다
<!--[if !supportLists]--> * io.sockets.in(‘roon name’).emit(‘event’,message)
‘room name’ room안에 있는 모든 클라이언트들에게 이벤트 보내기
<!--[if !supportLists]--> * socket.broadcast.to(‘roon name’).emit(‘event’,message)
‘room name’의 room 안에 있는 나를 제외한 다른 클라이언트들에게 이벤트 보내기
또한 현재 생성되어 있는 room에 대한 정보를 읽어오는 방법이 몇가지가 있는데,
<!--[if !supportLists]--> * io.sockets.manager.rooms
현재 생성되어 있는 모든 room의 목록을 리턴한다.
<!--[if !supportLists]--> * io.sockets.clients(‘roon name’)
‘room name’의 room 안에 있는 모든 클라이언트 소켓 목록을 리턴한다.
몇가지 주요 메서드들을 성명하였지만, 여기서 설명한 것은 일부에 불과하다. 상세한 내용들은 아래 내용을 참고하기 바란다.
상세한 Configuration 처리 https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO
이벤트 종류(disconnect 등) https://github.com/LearnBoost/socket.io/wiki/Exposed-events
자아 그러면 소개된 메서드들을 가지고, 앞에서 만든 채팅 프로그램의 기능을 더해보도록 하자.
출처: https://bcho.tistory.com/899?category=513811 [조대협의 블로그]
room 안에 있는 소켓 찾아오기 (ID 만)
var clients_in_the_room = io.sockets.adapter.rooms[Romm].sockets;
for (var clientId in clients_in_the_room ) {
console.log('client: %s', clientId); //Seeing is believing
// var client_socket = io.sockets.connected[clientId];//Do whatever you want with this
}
room 안에 있는 소켓 찾아오기 (객체)
var clients_in_the_room = io.sockets.adapter.rooms[groupMessageJsonObj.sendMessageContent.roomNo].sockets;
var socket_objects = [];
for (socketId in clients_in_the_room) {
socket_objects.push(io.sockets.connected[socketId]);
console.log('client: %s', socket_objects[0]);
var target_Id = userSocketMap.search(socket_objects[0]);
console.log('키값: %s', target_Id);
}
'node.js & js' 카테고리의 다른 글
node js Fcm 설치 (0) | 2019.05.14 |
---|---|
node.js 에서 Json 객체 받아서 사용하기 (0) | 2018.12.31 |
윈도우 node.js 설치 및 실행 (0) | 2018.12.28 |
socket.io 에서 on 이 여러번 실행되는 이슈 (0) | 2018.06.21 |
node js에서 fcm 푸시 메세지 보내기 (0) | 2018.06.15 |