-
socket.io (실시간 데이터 주고받기)Node.js,MongoDB 2022. 4. 27. 12:52
실시간으로 소통할 때 SSE말고도 WebSocket을 쓰면 서버, 유저간 실시간 통신이 가능하다.
Server Sent Event는 서버 -> 유저의 일방적 통신이라면,
WebSocket는 양방향 통신이 가능하다.
생js로 할 순 있는데, 라이브러리 사용이 편리하다.
npm install socket.io
먼저, socket.io를 설치해준다. 그리고,
const http = require('http').createServer(app); const { Server } = require("socket.io"); const io = new Server(http);
셋팅을 해준다. 세줄은 const app = express(); 밑에 작성해야 한다.
마지막으로,
//app.listen(8080, function(){ // console.log('listening on 8080') //}); //app대신 http로 교체 http.listen(8080, function(){ console.log('listening on 8080') });
이제, WebSocket을 오픈할 수 있는데, 유저가 보는 html파일에도 socket.io를 셋팅해야한다.
socket.ejs파일을 views폴더에 만들고, /socket에 접속하면 socket.ejs페이지를 보여주게 셋팅해보자.
app.get('/socket', function(요청, 응답){ 응답.render('socket.ejs') })
그리고, socket.ejs에도 socket.io를 설치해야 유저가 이용가능하다. ejs파일에
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.0/socket.io.js" integrity="sha512-/xb5+PNOA079FJkngKI2jvID5lyiqdHXaUUcfmzE0X0BdpkgzIWHC59LOG90a2jDcOyRsd1luOr24UCCAG8NNw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
socket cdn을 적어주는데, 서버에 설치한 버전과 동일한 cdn을 붙여넣기 해야한다.
이제 socket.ejs 파일에 script태그 안에 아래처럼 입력하면 접속할 수 있다. 위의 cdn보다 아래 작성해야한다.
var socket = io();//유저가 WebSocket접속하는 법
WebSocket접속 시 서버에서 뭔가 실행하고 싶으면,
io.on('connection', function(){ console.log('유저접속됨') })
위의 코드를 적어주면 된다.
이제 서버에게 웹소켓으로 실시간 메세지를 보내보자.
<button id="send">서버에 메세지 보내기</button>
서버에 메세지를 보내는 버튼을 하나 만들고,
//실시간 메세지를 웹소켓에 보내기 $('#send').click(function() { socket.emit('user-send','안녕하세요')//socket.emit(작명, 메세지) })
버튼을 클릭하면, socket.emit을 이용해 데이터를 보내준다.
그리고, server.js에서 서버가 수신하려면
io.on('connection', function(socket){ console.log('유저접속됨'); socket.on('user-send', function(data){//누가 'user-send'이름으로 메세지 보내면 내부코드 실행 console.log(data); }) })
이렇게 실행하는 코드의 함수에 socket 파라미터를 넣어 socket.on('작명한것', function(파라미터){}이렇게 적어주고 여기서 function함수 안에 들어간 파라미턴 안녕하세요 라는 받은 메세지를 뜻한다.
지금까진 유저가 서버에 메세지를 전송했다.
이제, 서버가 유저에게 메세지를 보내보자.
io.on('connection', function(socket){ console.log('유저접속됨'); socket.on('user-send', function(data){//누가 'user-send'이름으로 메세지 보내면 내부코드 실행 console.log(data); //서버 -> 유저 메세지 전송 io.emit('broadcast','반가워') }); })
이렇게, 유저가 서버한테 메세지를 보내면 안에서 io.emit('작명','보낼내용')으로 서버에서 유저한테 보낼 수 있다. 그리고
유저도 메세지를 받으려면 socket.ejs에서
socket.on('broadcast',function(data){ console.log(data) })
위 처럼 적어준다. 서버가 broadcast란 이름으로 데이터를 보낸걸 받는다는 뜻이다.
여기서, io.emit()은 모든 유저에게 메세지를 보내준다. 이걸 전문용어로 broadcast한다라고 한다.
io.emit을 쓴 이유는 보통 채팅에서 한명이 안녕이라고 하면 여러명에게 뿌려주므로 사용한다.
그래서 코드를
socket.on('user-send', function(data){ console.log(data); io.emit('broadcast',data); });
이렇게 적으면, 유저가 메세지를 보내면 data파라미터에 담기고 io.emit으로 모두에게 그 메세지를 보내주세요가 된다.
이제, console.log창이 아니라 div박스를 만들어서 서버에서 메세지를 받으면 div로 보여주게 코드를 짜보자.
<div id="content"></div>
socket.on('broadcast',function(data){ $('#content').append('<div>'+data+'</div>') })
socket.ejs에 이렇게 div를 만들고, 서버에서 보낸 메세지를 받아서 div박스에 append해주면 담기게 된다
만약, 서버와 유저간 단독으로 소통을 하고싶으면 io.emit() 이 아니라 io.to(socket.id).emit() 이렇게 적으면 socket.id를 가진 사람에게만 메세지를 보내줄 수 있다. socket.id란 function의 socket파라미터에는 유저의 정보가 담기는데, 거기중에 id를 뜻한다. 즉, 접속한 사람마다 고유의 id가 생긴다.
마지막으로, 채팅방을 만들어보자.
서버에서 채팅방을 만들고 입장은 socket.join(방이름)이렇게 쓴다.
io.on('connection', function(socket){ console.log('유저접속됨'); socket.join('room1') socket.on('user-send', function(data){//누가 'user-send'이름으로 메세지 보내면 내부코드 실행 console.log(data); //서버 -> 유저 메세지 전송 io.emit('broadcast',data); }); })
그리고 socket.ejs에서
<button id="room1">채팅방1 입장</button>
채팅방입장 버튼을 만들어주고,
$('#room1').click(function(){ //서버한테 room1에 입장시켜줘 이러고 보내면 되는데, //socket쓸 땐 GET/POST요청 대체가능 socket.emit('joinroom','채팅방입장시켜줘') })
room1을 클릭하면 socket.emit으로 joinroom이라는 이름으로 '채팅방입장시켜줘'란 메세지를 보내주면 된다.
그리고
socket.on('joinroom', function(data){ socket.join('room1') })
socket.on으로 joinroom이란 이름으로 보내주면 socket.join으로 room1에 입장시켜줘 라고 보내준다.
<button id="room1-send">채팅방1에서 채팅하기</button>
그리고, 채팅방1을 눌러서 입장하고, 채팅방1에서 채팅하기 버튼을 만들어서
$('#room1-send').click(function(){ socket.emit('room1-send','반가워 채팅방1 사람들아') })
버튼을 누르면 socket.emit으로 room1-send경로로 '반가워 채팅방1 사람들아'라는 메세지를 보내주면 된다. 그리고 server.js 에서
socket.on('room1-send', function(data){ io.to('room1').emit('broadcast',data); });
socket.on을 이용해 room1-send경로로 io.to('room1')로 room1에만 메세지를 보내주면 된다.
그러면, 시크릿모드에선 안보이다가 채팅방1에 입장한 사람만 보이게 된다.
'Node.js,MongoDB' 카테고리의 다른 글
채팅기능 만들기 (DB변동사항 실시간 업데이트) (0) 2022.04.27 채팅기능 만들기 (서버와 실시간 소통 SSE) (0) 2022.04.25 채팅기능 만들기 (메시지 발행) (0) 2022.04.25 채팅기능 만들기 (채팅방만들기) (0) 2022.04.22 쇼핑몰 등 실제 서비스에서 질문등? (0) 2022.04.20