-
노드js (Node.js) 소켓 (Socket) 예제MEAN STACK/Socket programming 2018. 9. 12. 10:18
웹 어플리케이션을 개발할 때 MEAN STACK을 사용하는 가장 큰 이유 중 하나가 소켓 프로그래밍(Socket Programming)이라고 한다. c에서는 소켓 구조체에 서버의 정보를 직접 구조체에 입력하고, 데이터 저장 방식 또한 호환이 되도록 인디언을 고려하는 등의 번거로움을 겪어야 한다. 노드js 에서는 소켓 모듈을 지원해 이러한 번거로움을 회피해 개발할 수 있는 편리함을 제공한다.
서버 작동시키기 위한 c 코드. 소켓 구조체를 통해 인디언 방식, 포트번호, 프로토콜 등을 직접 지정해줘야 한다.
npm 명령어들을 통해 express, socket.io를 설치 후 js 코드 작성한다.
소켓 모듈의 주요 메소드와 주석을 통해 코드를 이해하면메소드명설명on('메소드명', 콜백함수(data){})소켓 연결된 상대편(브라우저 / 서버)에서 메소드명을 매개변수로 갖는 emit 호출하면 이후 콜백함수가 동작한다. emit 메소드의 매개변수를 data로 받아와 적절한 동작을 수행한다.on('connection', function(socket))소켓 연결을 위해 필수적으로 수행되어야 하는 함수.
jQuery에서 $().ready()와 같은 느낌으로 사용하면 된다.
function의 매개변수로 소켓 객체를 사용할 수 있다.emit('메소드명', data)소켓 연결된 상대편(브라우저 / 서버)에서 메소드명을 갖는 on 함수를 호출 한다. 이때 on 함수에 필요한 데이터를 data로 함께 전송한다.join("공간명")'공간명'을 키로 해 소켓들을 관리할 수 있게 해주는 메소드./** * Created by Admin on 2017-05-10. */ const http = require('http'); const socketio = require('socket.io'); const fs = require('fs'); const express = require('express'); const app = express(); // static 폴더 경로 지정해준다. html 파일에서 src 요청할 때 매개변수로 지정해준 경로 이후부터 작성하면 된다. app.use(express.static(__dirname + '/public')); // http의 createServer에서 사용할 때 express를 매개변수로 넣어준다. const server = http.createServer(app); server.listen(3000, function(){ console.log("Server running 3000"); }); // 연결할 http 서버 객체 매개변수로 사용해 소켓 연결 // src에서 이 객체를 사용한다. const io = socketio.listen(server); // on : 이벤트를 만들어라 connection은 예약어 io.sockets.on('connection', function(socket){ console.log("브라우저 연결 : " + socket.id); // 접속한 브라우저 객체를 특정 공간에 등록. socket.join("chat"); // broadcast라는 메소드 socket 통해 호출되면 매개변수로 전달된 data와 함께 적당한 로직 수행 socket.on("broadcast", function (data) { // chat 공간에 등록된 브라우저들에 특정 이벤트 수행 io.sockets.in("chat").emit('receive', data); }); }); // socket.io 사용시 Http 모듈로 Express를 실행한다. app.use(function(request, response){ fs.readFile("client.html", "utf-8", function(err, data){ response.type('text/html'); response.send(data); }) ; });
index.js
처음에 소켓 연결을 하면 join 메소드를 통해 브라우저가 'chat' 키를 갖도록 한다.
이후 브라우저에서 broadcast를 키로 하는 emit 메소드가 브라우저(html 파일)에서 호출된다면 emit 메소드에서 함께 보낸 데이터(data)를 'chat' 키를 갖고 있는 브라우저들에게 emit 메소드를 통해 전송한다. 이렇게 하면 데이터를 한번에 여러명에게 보낼 수 있고, 다대다 통신이 가능하다는 말이다.<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript" src="/jquery-3.2.1.min.js"></script> <script type="text/javascript"> $().ready(function(){ // 서버쪽은 크롬에서 const를 인식하지만 브라우저가 보는 파일들은 const나 let 사용 // 시 인식 불가 var socket = io.connect(); socket.on("receive", function (data) { $("#chatMessages").append( $("<div>"+data+"</div>") ); }); $("#button").click(function(){ var chat = $("#chat").val(); socket.emit("broadcast", chat); $("chat").val(""); $("chat").focus(); }); }); </script> </head> <body> <input type="text" name="chat" id="chat" placeholder="내용을 입력하세요"/> <input type="button" id="button" value="send" /> <br/> <div id="chatMessages"></div> </body> </html>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
다음과 같이 소켓의 경로를 설정해줘야 사용할 수 있는데, 이는 모듈의 경로가 아닌 js 코드의 소켓 객체 경로를 가리킨다.
소켓 객체를 선언하는 순간(const io = socketio.listen(server); ) 을 가져와 브라우저에서도 소켓 객체를 사용할 수 있는 것이다(io.connect 등).
※src는 객체명과 관련없이 항상 같게 적으면 된다. (js 파일에서 고려할 사항이 없다는 말)다음과 같이 서버로 접속하면 모든 사람들이 글을 볼 수 있다. 이를 조금 더 발전시킨다면 그럴싸한 채팅 프로그램도 개발이 가능할 것이라고 생각한다.