Websockets & Server-Sent Events
아래 내용의 출처는 https://www.sitepoint.com/real-time-apps-websockets-server-sent-events/ 이며, 정확한 번역이 아니며, 제가 사용하기 위해 번역한 내용입니다.읽고 참곤는 가능하지만 공유는 하지 말아주시기 바랍니다.
WebSockets
먼저 Command창에 아래의 코드를 입력한다.
git clone https://github.com/r2fresh/websocket-demo.git cd websocket-demo npm install npm start
브라우저에서 localhost:8080을 입력하면 서버에서, 3초에 한번씩 Hello hello!을 보내준다.각 Client와 Server의 소스코드는 아래와 같다.
Client
// Open a connection var socket = new WebSocket('ws://localhost:8081/'); // When a connection is made socket.onopen = function() { console.log('Opened connection 🎉'); // send data to the server var json = JSON.stringify({ message: 'Hello 👋' }); socket.send(json); } // When data is received socket.onmessage = function(event) { console.log(event.data); } // A connection could not be made socket.onerror = function(event) { console.log(event); } // A connection was closed socket.onclose = function(code, reason) { console.log(code, reason); } // Close the connection when the window is closed window.addEventListener('beforeunload', function() { socket.close(); });
Server
var WSS = require('ws').Server; // Start the server var wss = new WSS({ port: 8081 }); // When a connection is established wss.on('connection', function(socket) { console.log('Opened connection 🎉'); // Send data back to the client var json = JSON.stringify({ message: 'Gotcha' }); socket.send(json); // When data is received socket.on('message', function(message) { console.log('Received: ' + message); }); // The connection was closed socket.on('close', function() { console.log('Closed Connection 😱'); }); }); // Every three seconds broadcast "{ message: 'Hello hello!' }" to all connected clients var broadcast = function() { var json = JSON.stringify({ message: 'Hello hello!' }); // wss.clients is an array of all connected clients wss.clients.forEach(function each(client) { client.send(json); console.log('Sent: ' + json); }); } setInterval(broadcast, 3000);
브라우저 호환성
현재 Opera mini만을 빼고 최근 업데이트 된 브라우저에서는 모두 지원을 하고 있으며, 보다 자세한 내용은 아래의 링크를 참고 하면 된다.
http://caniuse.com/#feat=websockets
디버깅
디버깅은 Chrome과 같은 경우 inspect에서 Network > WS > Frams에서 확인이 가능하며, Firefox는 Websocket Monitor addon을 사용하여 가능하다.
Server-Sent Events
SSE로 위의 WebSocket와 같은 기능을 구현해 보도록 하겠습니다.
먼저 아래와 같이 설치를 합니다.
git clone https://github.com/r2fresh/server-sent-events-demo.git cd server-sent-events-demo npm install npm start
브라우저에서 localhost:8080을 입력하면 Websocket과 같이, 3초에 한번씩 Hello hello!을 보내준다. 각 Client와 Server의 소스코드는 아래와 같다.
Client
// Open a connection var stream = new EventSource("/sse"); // When a connection is made stream.onopen = function() { console.log('Opened connection 🎉'); }; // A connection could not be made stream.onerror = function (event) { console.log(event); }; // When data is received stream.onmessage = function (event) { console.log(event.data); }; // A connection was closed stream.onclose = function(code, reason) { console.log(code, reason); } // Close the connection when the window is closed window.addEventListener('beforeunload', function() { stream.close(); });
Server
var SSE = require('sse'); var http = require('http'); var server = http.createServer(); var clients = []; server.listen(8080, '127.0.0.1', function() { // initialize the /sse route var sse = new SSE(server); // When a connection is made sse.on('connection', function(stream) { console.log('Opened connection 🎉'); clients.push(stream); // Send data back to the client var json = JSON.stringify({ message: 'Gotcha' }); stream.send(json); console.log('Sent: ' + json); // The connection was closed stream.on('close', function() { clients.splice(clients.indexOf(stream), 1); console.log('Closed connection 😱'); }); }); }); // Every three seconds broadcast "{ message: 'Hello hello!' }" to all connected clients var broadcast = function() { var json = JSON.stringify({ message: 'Hello hello!' }); clients.forEach(function(stream) { stream.send(json); console.log('Sent: ' + json); }); } setInterval(broadcast, 3000)
Sending Events from the Server
Websocket과 같은 경우에는 Client에서 Server로 메세지를 보내는 API가 있지만 SSE같은 경우에는 따로 존재하지 않는다. 하지만 기존의 Ajax를 사용하여 Client에서 Server로 메세지를 전송할 수 있다.
아래는 간단한 server와 Client의 소스 코드이다.
Server
http.createServer(function(req, res) { // Open a long held http connection res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); // Send data to the client var json = JSON.stringify({ message: 'Hello 👋' }); res.write("data: " + json + "\n\n"); }).listen(8000);
Client
document.querySelector('#send').addEventListener('click', function(event) { var json = JSON.stringify({ message: 'Hey there' }); var xhr = new XMLHttpRequest(); xhr.open('POST', '/api', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(json); log('Sent: ' + json); });
브라우저 호환성
SSE 경우 WebSocket보다 지원브라우저가 적지만, 다행히 Polifill for EventSource를 사용하여 사용이 가능하다. 지원 가능 브라우저 목록은 아래의 링크를 참고하면 된다.
http://caniuse.com/#feat=eventsource
디버깅
디버깅 경우 크롬에서 Network > XHR > EventStream에서 확인하고 디버깅이 가능하다.
Conclusion
이번 글에서만 보면 WebSocket이 더 좋아 보이는 기능인듯 하지만, 실시간 브라우저간의 통신이 아니라면 SSE를 사용하는 것이 더 나을 수도 있다. WebSocket은 채팅과 같은 경우에서 사용하고, SSE는 주식과 같이 서버에서 던져주는 것을 바로 실시간으로 보이는 곳에서 사용하는 것이 좋을듯 하다.








