Enjoy Programming

Socket IO 본문

JavaScript/Node.JS

Socket IO

LEETAEEON 2021. 8. 8. 20:25

Socket.IO 는 WebSocket을 기반으로 클라이언트와 서버의 양방향 통신을 가능하게 해주는 자바스크립트 라이브러리이다.

브라우저와 Node.js용 서버 측 라이브러리, 두 부분으로 구성된다.

 

먼저 MDN에서 websocket이 무엇인지 살펴보자.

 

웹 소켓은 브라우저와 서버 사이의 인터액티브 통신 세션을 설정할 수 있게 하는 고급 기술이다.

개발자는 웹 소켓 API를 통해 서버로 메세지를 보내고 서버의 응답을 위해 서버를 폴링하지 않고도 이벤트 중심 응답을 받는 것이 가능하다.

 

HTTP를 생각해보면 HTTP는 stateless 이다. 그래서 클라이언트에 접속해서 서버로 get이나 post요청을 하게되면

응답이 이루어지게 되는데 이 하나의 과정이 끝나면 서버와의 연결이 끊긴다.

서버가 유저를 지속적으로 기억하게 하는 방법은 쿠키를 생성하는 방법뿐이다.

 

웹소켓은 stateful하다. 서버가 어떤 클라이언트 어떤 유저와 연결되어 있는지 기억을 하고 있다는 말이다.

지속적으로 유저와 연결이 이루어지고 있는 상태이다.

 

한마디로 HTTP와는 다른 지속적인 연결이 유지되는 통신 프로토콜이다.

 

Socket.io는  이러한 WebSocket 을 쉽게 구현하기 위한 라이브러리이다.

https://socket.io/

 

Socket.IO

SOCKET.IO 4.0 IS HERE ~/Projects/tweets/index.js const io = require('socket.io')(80); const cfg = require('./config.js

socket.io

자 이제 socket.io를 이용해서 http 위에 websocket 서버를 올려보자.

보통은 같은 포트에 2개의 서버를 동시에 동작할 수 는 없지만. 

서로 다른 프로토콜인 http와 websocket은 동시에 가능하다.

 

상기 코드는 기본적인 express 서버 구동코드이다.

기본적인 http서버를 server라는 변수에 담아주고  const IO = socketIO(server) 로 담아주면 ws서버도 같이 올릴 수있다.

한번 접속 해보자

 

브라우저의 주소창에 /socket.io/socket.io.js 로 접속해보면 이렇게 접속이 가능하다.

기본적으로  socket.io는 WebSocket Client와 WebSocket Server 두가지 역할을 할 수 있다.

서버도 구동할 수 있고 클라이언트도 프로그래밍 할 수 있다.

위 url로 접속하면 나타나는 모습은 프런트엔드 코드인데. socket.io 백엔드와 프론트엔드가 서로 커뮤니케이팅을 할 수 있게 해주는 코드이다.

 

다시  정리하면 server라느 변수를 만들어서 SocketIO에 서버를 전달한다.

그렇게 하고서 다시 io라는 변수에 담아주는데 이는 io가 모든 이벤트를 알아야 하기 때문에 만들어주는 것이다.

 

http는 get/post/delete/put과 같은 method를 가지고 있다. 그리고 이들은 라우터를 가지고 있는데

socket은 페이지가 없고 오직 연결만이 있다. 서버, 클라이언트, 유저는 이벤트를 이 연결로 보낼 수 있고 받을 수 있다.

 

socket의 이벤트에서 가장 중요한 것은 connection이다. 한번 코드를 적어보자.

 

 

on 메서드를 이용하는데 addEventListener와 비슷한 역할을 하는 듯하다. io가  connection이라는 이벤트가 들어왔을 때

 callback 으로 접속중이라고 로그를 띄워 줘 본다.

 

express에서 log확인을 위해 morgan을 설치해주고 로깅을 해보자.

아! 한가지 더 해줘야 하는게 있는데

home 템플릿에 위 처럼 스크립트를 넣어준다.

그리고 프론트 파일인 index.js에 io("/") 를 실행하도록 해주면.

해당 4000번 포트로 접속을 하게 되면 이렇게 접속중이 뜨게 된다. 

그리고 또 다른 창을 열어 접속을 하게 되면 모두 접속중이 뜨게 된다. 한명 두명 세명 여러명이 접속하는 것이 다 콘솔에 찍힌다.

 

연결된 여러명의 socket중 어느 클라이언트의 이벤트인지 알 수 있어야 할 필요가 있다.

그럼 코드를 약간 수정해보자.

접속시 마다 socket이라는 인자를 받아서 출력해보면 터미널창에 엄청나게 많은 로그가 뜨는데.

현재 두개의 창으로 접속을 해있어서 두개의 socket object가 나오고 이 안을 살펴보면 서로 다른 고유의 id를 가지고 있다.

그럼 이 id를  배열에 담아 한번 확인 해보자.

setInterval 함수를 이용해 2초마다 socket.id를 가진 배열을 출력하도록 했다 . 현재 두개의 창에서 접속해있어서 이렇게 두개가 뜬다.

 

자 한가지 알고 넘어가야할 것을 하나 시도해보면 여기서 서버를 꺼보면

 

브라우저는 지속적으로 해당 서버를 찾기위해 시도를 하고 있다. 다시 켜보자

다시 켜보면 해당 클라이언트를 자동적으로 다시 잡아준다. id값은 바뀌었지만~

 

자 넘어가서~ 이번에는 클라이언트에 메세지를 전송해보자!

그전에 알아야할 메소드가 있는데

위와 같다. 여기서 먼저 emit과 broadcast.emit을 사용해보겠다.

connection이란 이벤트를 발생하면 callback으로 socket에 emit을 통해  Join이라는 event를 다시 발생시킨다.

이때 heelo라는 메세지를 전달하게 되는데

클라이언트 측에서 한번 이 메세지를 출력해보자

socket이 Join이라는 이벤트를 받게 되면 data를 인자로 받고 이 데이터를 출력하면

서버측에서 보낸 메세지가 출력이 된다. 데이터는 뭐 object로 보내도 상관이없다. 한번 보내보자

역시 무리없이 출력이 된다.

 

이번엔 broadcast를 이용해보는데 broadcast는 메세지를 전송한 클라이언트를 제외한 모든 클라이언트에게 전송이 된다.

 

그냥 emit을 했을때는 두개의 창에서 모두 data를 전송 받았지만  broadcast를 이용하면

refresh? rerendering이 이루어지는 고로 메세지를 보내는 클라이언트는 콘솔 메세지 출력이 되지 않고

받고 있는 클라이언트만 메세지가 콘솔에 출력됨을 볼 수 있다.

 

이번에는 클라이언트에서 서버로 한번 보내보자.

클라이언트 측에서 emit을 이용해서 event를 발생시킨다 . event이름은 MYMY 이고 msg는  obj로 넘긴다.

이제 서버측에서 받아주면 되는데

어려운 것은 아니다. 이렇게 해주면 브라우저에 접속이 될 때마다 서버측 터미널에 띄워준다,

요기까지가 기본적인 socket.io동작을 테스트 해봤다.

 

중요한 것은 위 에서 socket은 이벤트가 발생되는 하나의 socket이다! 라는점 명심하자.

'JavaScript > Node.JS' 카테고리의 다른 글

Iron session  (0) 2022.05.15
socket.io 간단한 채팅 테스트  (0) 2021.08.09
좋아요 구현하기  (0) 2021.07.12
Product && develop Environment  (0) 2021.06.30
Github and aws s3 - 2  (0) 2021.06.29