3. Socket.IO
JavaScript 를 이용하여 실시간 어플리케이션을 구축할 수 있도록 하는 엔진.
양 방향의 이벤트 기반의 통신이 가능하고, 모든 플랫폼과 장치에서 동작
실시간으로 차트나 로그 데이터를 전달하여 표시
실 시간 분석
몇 줄의 코드만으로 채팅 어플리케이션 개발 가능
인스턴스 메신져
이미지, 오디오, 비디오 같은 이진 데이터 전달 가능
바이너리 스트리밍
상대방의 수정 내역을 보면서 동시 문서 수정
문서 협업
4. Hello Socket.IO
Express 와 Http 모듈과 연동하여 웹 통신 포트로 실시간 서버 구축 가능
웹 파일에서는 Socket.IO 클라이언트가 제공되어 손쉽게 구축 가능
$ npm install socket.io
Socket.IO 설치
<script
src='/socket.io/socket.io.js'></script
>
<script>
var socket = io();
socket.on('news', function(data){
document.write(JSON.stringify(data));
socket.emit('feedback',{ hello :
'world2' });
});
</script>
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
// 기본 접속 경로
app.get('/', function (req, res) {
res.sendFile(__dirname +
'/sample1.html');
});
// 외부 접속시 처리
io.on('connection', function (socket) {
// 접속한 모든 클라이언트에 전달
socket.emit('news', { hello: 'world1' });
// Client 로 부터 수신받는 event
socket.on('feedback', function (data) {
console.log(data);
});
});
6. Unicast, Multicast
특정 소켓 혹은 접속한 모든 소켓에 데이터를 전달하는 방식
Socket.IO 에서 손쉽게 데이터를 전달 할 수 있게 함
BroadcastUnicast
7. Unicast & Broadcast 구현 (Server)
Unicast 를 위해서는 보내려는 특정 소켓을 가리켜야 함
Broadcast 는 socket 의 broadcast 를 이용하여 전달 가능
// Broadcast
socket.on('broadcast', function (data) {
console.log('Broadcast : ' + data);
socket.broadcast.emit('msg', data);
});
// Unicast
socket.on('unicast', function(data){
console.log('Unicast : ' + data);
sock.emit('msg', data);
});
// Send All!
socket.on('sendall', function(data){
console.log('Sendall : ' + data);
io.emit('msg', data);
});
});
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
// 기본 접속 경로
app.get('/', function (req, res) {
res.sendFile(__dirname + '/sample2.html');
});
// 첫번째 접속
var sock = undefined;
// 외부 접속시 처리
io.on('connection', function (socket) {
// 접속한 모든 클라이언트에 전달
socket.emit('news', { hello: 'world1' });
if(!sock){
sock = socket;
}
8. Unicast & Broadcast 구현 (Client)
jQuery 와 Socket.IO 클라이언트를 이용하여 웹 페이지 구성
Unicast, Broadcast 를 확인할 수 있도록 버튼 구성
$('#unicast').click(function(){
sendMsg('unicast');
});
$('#broadcast').click(function(){
sendMsg('broadcast');
});
$('#sendall').click(function(){
sendMsg('sendall');
});
});
</script>
</head>
<body>
<input type='text' />
<p/>
<button id='unicast'>Unicast</button>
<button id='broadcast'>Broadcast</button>
<button id='sendall'>Sendall</button>
<div id='msgs'/>
</body>
</html>
<html>
<head>
<title>Hello Pi!</title>
<script src='https://code.jquery.com/jquery-
3.1.1.min.js'></script>
<script src='/socket.io/socket.io.js'></script>
<script>
$(function(){
var socket = io();
var id = 'Guest_' + Math.floor((Math.random() * 10) + 1);
socket.on('msg', function(data){
$('#msgs').append($('<p>').text('ID : ' + data.id + ' : ' +
data.msg));
});
var sendMsg = function(type){
var msg = $('input').val();
$('#msgs').append($('<p>').text('ME : ' + id + ' : ' +
msg));
socket.emit(type, { id : id, msg : msg});
$('input').val('');
}
10. Multicast 구현
Multicast 는 접속한 클라이언트에서 특정 클라이언트 그룹만 데이터 전달
Socket.IO 에서는 Namespace 혹은 Room 으로 구현 가능
Multicast
특정 Namespace 를 지정하여 별도의 커넥션 관리
Namespace 를 이용한 구현 방법
방명에 Join, Leave 하는 식으로 데이터 처리
Room 을 이용한 구현 방법
P : 코드에 명시적으로 Multicast 대상이 구분됨
N : Multicast 대상 마다 코드가 늘어 남
P : 별다른 코드 추가 필요 없음. 간단한 구조
N : Multicast 대상이 명시적으로 표현 안됨
11. Multicast with Namespace (Server)
Unicast 를 위해서는 보내려는 특정 소켓을 가리켜야 함
Broadcast 는 socket 의 broadcast 를 이용하여 전달 가능
// Namespace2
app.get('/nsp2', function (req, res) {
res.sendFile(__dirname + '/nsp2.html');
});
var nsp2 = io.of('/namespace2');
nsp2.on('connection', function (socket) {
socket.emit('new', { namespace: 'nsp2' });
socket.on('broadcast', function (data) {
console.log('Nsp2 : ' + data);
socket.broadcast.emit('msg', data);
});
});
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
// Namespace1
app.get('/nsp1', function (req, res) {
res.sendFile(__dirname + '/nsp1.html');
});
var nsp1 = io.of('/namespace1');
nsp1.on('connection', function (socket) {
socket.emit('new', { namespace: 'nsp1' });
socket.on('broadcast', function (data) {
console.log('Nsp1 : ' + data);
socket.broadcast.emit('msg', data);
});
});
12. Multicast with Namespace (Client)
Namespace 를 이용하여 서버 구현 시, 클라이언트 접속 인자로 Namespace
이름을 입력하여 사용해야 함
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io('/namespace2');
var count = 0;
socket.on('new', function(data){
document.write(count++ + ' / ' +
JSON.stringify(data));
socket.emit('broadcast',{ name : 'namespace1' });
});
socket.on('msg', function(data){
document.write(count++ + ' : ' +
JSON.stringify(data));
});
</script>
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io('/namespace1');
var count = 0;
socket.on('new', function(data){
document.write(count++ + ' / ' +
JSON.stringify(data));
socket.emit('broadcast',{ name : 'namespace1' });
});
socket.on('msg', function(data){
document.write(count++ + ' : ' +
JSON.stringify(data));
});
</script>
Nsp2.htmlNsp1.html
13. Multicast with Room (Server)
Room 방식을 사용 시는 방 접속 시 join, 나올 땐 leave 함수를 사용
해당 Room 의 Socket 에 데이터를 보내기 위해서 to(방명)을 이용
socket.on('leave', function (data) {
console.log('Leave : ' + data.id + ' / '
+ data.room + ' Leaved!');
socket.leave(data.room);
io.to(data.room).emit('leave', data);
});
socket.on('msg', function (data) {
console.log('msg : ' + data.id + ' / ' +
data.room);
socket.broadcast.to(data.room).emit('msg',
data);
});
});
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
app.get('/', function (req, res) {
res.sendFile(__dirname + '/room.html');
});
io.on('connection', function (socket) {
console.log('connected');
socket.on('join', function (data) {
console.log('Join : ' + data.id + ' / '
+ data.room + ' Joined!');
socket.join(data.room);
io.to(data.room).emit('join', data);
});
14. Multicast with Room (Client)
클라이언트 측에서 Room 에 접속을 위해 별도로 할 작업은 없음
방명을 전달하여 서버 측에서 처리 해야 함
$('#room2').click(function(){
room = 'room2';
socket.emit('join', { id : id, room : 'room2'});
});
$('#send').click(function(){
var msg = $('input').val();
$('#msgs').append($('<p>').text('ME : ' + id + ' : ' + msg));
socket.emit('msg', { id : id, msg : msg, room : room});
$('input').val('');
});
});
</script>
</head>
<body>
<input type='text' />
<p/>
<button id='room1'>ROOM1 Join</button>
<button id='room2'>ROOM2 Join</button>
<button id='send'>Send</button>
<div id='msgs'/>
</body>
</html>
<html>
<head>
<title>Hello Pi!</title>
<script src='https://code.jquery.com/jquery-
3.1.1.min.js'></script>
<script src='/socket.io/socket.io.js'></script>
<script>
$(function(){
var socket = io();
var id = 'Guest_' + Math.floor((Math.random() * 10) + 1);
var room = 'room1';
socket.on('join', function(data){
$('#msgs').append($('<p>').text('ID : ' + data.id + ' : ' +
data.room + ' Joined!'));
});
socket.on('msg', function(data){
$('#msgs').append($('<p>').text('ID : ' + data.id + ' : ' +
data.msg));
});
$('#room1').click(function(){
room = 'room1';
socket.emit('join', { id : id, room : 'room1'});
});
15. W www.circul.us G group.circul.us
S social.circul.us C cafe.circul.us
CONTACT.US circulus@circul.us
THINKER TO MAKER
ANY
QUESTION?
x
Notas del editor
Circulus 팀 박종건입니다. 위 사진은 작년 창조경제박람회때 포스터 운반하던 파이보의 모습입니다.
파이보와 함께 펼쳐가는 미래를 이야기 하겠습니다.