ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 항해 99 5기 TIL_68
    항해 99 2022. 3. 18. 03:41

    ▶ Today I Learned

     

    <실전 프로젝트>

     

    [화상 채팅]

     

    현재 WebRTC의 simple peer 를 사용 중이다.

    그렇다면 각각의 방식부터 알아보자.

     

    P2P(Peer to Peer, Mesh 라고도 함) 방식

     

    서버는 클라이언트 간 연결(정보 signal 중계)을 주관만 할 뿐 영상과 같은 데이터 교환은 클라이언트단에서 일어남 -> 유저 pc에 많은 부하 발생,

    peer 간 직접 연결로 데이터를 송수신하기 때문에 실시간성이 보장됨

    다른 방식에 비해 레퍼런스가 많음

     

    이를 구현하는 방식 중 널리 쓰이는 것이 simple peer와 peerJS 이다. 하단 링크 참조

    https://www.npmtrends.com/easyrtc-vs-peerjs-vs-simple-peer-vs-simplewebrtc

     

    simple peer와 peerJS 둘다 webrtc를 좀 더 편하게 구현하는 것이 목적이다.

    차이점이 있다면 ...  사실 명확치 않다.

     

    P2P 방식의 webrtc 라이브러리가 대표적으로 simple-peer와 peerjs가 있었는데, 2개 다 레퍼런스가 그다지 많지 않았다. 2가지를 비교하는 자료도 없었기에 2가지를 어느 정도 따라 해보고 선택하는 게 최선의 방법이었다. 결론은 simple-peer를 사용하는 괜찮은 레퍼런스를 찾아서 그것을 선택했다.

     

    => 현재 우리의 경우 낮은 성능의 서버를 쓰기 때문에 해당방식 가능한 선택이긴 했다.

    유저수가 많을 때에 일어나는 급격한 성능 저하를 보완하기 위해 인원 수를 제한 (화상채팅 참가자는 최대 4명까지만 가능)

     

    cf) signaling?

    RTCPeerConnection이 생성되기 이전에 서로 다른 네트워크에 있는 2개의 디바이스들끼리의 통신을 위해 각 디바이스들의 위치를 발견하는 방법과 미디어 포맷에 대한 협의가 필요하다. 이 과정을 Signaling이라고 부름

     

    출처:

    https://jinhyukoo.github.io/js/2020/12/19/WebRTC%EC%99%80-PeerJS.html

     

    SFU 방식 (Selective Forwarding Unit 방식)

    클라이언트 간 데이터 교환(영상데이터까지)을 중앙 서버에서 수행,

    유저 pc에 부하가 적어 대규모 연결에 적합

    But 그만큼 높은 성능의 서버를 써야 한다. (대용량 트래픽을 감당할 수 있어야 함.)

    영상데이터를 서버로 보내기 때문에 실시간성이 p2p에 비해서 떨어진다.

     

     

    MCU 방식 (Multi-point Control Unit)

     

    SFU와 동일하게 데이터를 각 유저들이 아닌 서버로만 보내면 되지만

    Downlink로 받는 것은 유저각각의 peer가 아닌 통합된 하나의 peer 이다.

     

    즉, 다수의 송출 미디어를 중앙 서버에서 혼합(muxing) 또는 가공(transcoding)하여 수신측으로 전달하는 중앙 서버 방식이다.
    ex) 5인이 WebRTC 연결을 한다면 자신을 제외한 다른 4인의 video 데이터를 하나의 video 데이터로 편집하고, audio 데이터도 마찬가지로 편집하여 한 명에게 보낸다. 이 작업을 남은 4명에게도 동일하게 적용한다.

     

    그러다보니 중앙 서버 컴퓨터의 매우 높은 성능이 요구된다.

    또한 실시간성이 위 두가지 방식과 비교해 떨어진다.

     

    출처:

    https://surprisecomputer.tistory.com/8

     

    [예상 질문들 답변 정리]

     

    <Mysql을 사용하는 이유>

     

    유저, 방, 뱃지, 참가자 등 관계가 많아서 nosql을 쓰면 데이터 중복이 많이 발생할 것 같아서 SQL을 사용했다. 그 중 특히 MySQL을 선택한 것은 저사양에서도 괜찮은 성능을 낼 수 있고, sequelize와 함께 가장 많은 레퍼런스를 쉽게 찾을 수 있기 때문이다.

    주간 기록이나 월간 기록 같은 것들은 현재는 MySQL을 이용해 구현해 놨지만 SQL의 장점을 활용할 수 있는 부분이 없고 데이터 저장에 있어서 document 형식이 어울릴 것 같아서 여유가 된다면 noSQL로 이전을 계획중이다.

     

    (SQL의 가장 큰 특징은 NoSQL과 달리 엄격한 ‘스키마’와 ‘관계’가 있다는 것,

    기존에 짜놓은 구조에 맞는 데이터가 아니면 들어갈 수 없음, 또한 데이터를 종류별로 나눠놓고 관계를 설정하기에 각각의 테이블에는 중복된 데이터가 들어갈 수 없음)

    참고: https://siyoon210.tistory.com/130

     

    <Sequelize를 왜 사용하는 건가요?(ORM, Object Relational Mapping, sequelize는 node.js의 ORM 프레임워크)>

     

    별도로 SQL문을 짤 필요없이 객체를 통해 간접적으로 데이터베이스를 조작할 수 있게 된다.

    미리 짜놓은 메서드들을 재활용할 수 있어 유지 보수가 편리하다.

    표현이 직관적이라 가독성이 좋다 ex) db.room.HasMany(db.like{})로 일대 다 표현

     

    (단점? ORM으로 모든 것을 해결할 수는 없음, 프로젝트의 복잡성이 커질수록 부족한 설계로 인해 잘못 구현될 수 있음)

     

    <로그인 방식은 왜 jwt방식인가요?>(쿠키, 세션, jwt 중)

     

    Jwt 방식이 보안에 더욱 뛰어나기 때문.

     

    쿠키의 경우 보안에 취약함 (브라우저에 저장되는 데이터이기 때문에 정보를 탈취당할 우려가 있음)

     

    세션은 쿠키에 비해 보안에 좋음,

    클라이언트의 로그인 요청에 대한 응답을 작성할 때, 인증 정보는 서버에 저장하고 클라이언트 식별자인 JSESSIONID를 쿠키에 담게 됨

    이후 클라이언트는 요청을 보낼 때마다, SESSIONID 쿠키를 함께 보냄

    그러나 해커가 이를 중간에 탈취하여 클라이언트인척 위장할 수 있다는 한계가 존재

    (게다가 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부하가 심해질 수 있음.)

     

    jwt의 경우 암호화된 토큰을 헤더에 실어 서버로 보내는 방식으로 로그인을 인증

    jwt는 .을 구분자로 나누어지는 세 가지 문자열의 조합이며 각각은 Header, Payload, Signature라고 칭함

    header에는 암호화 해싱 알고리즘과 토큰의 타입(여기선 jwt), payload는 클라이언트의 ID 값 등 담을 정보, signature에는 인코딩된 Header 와 Payload를 더한 것을 비밀키로 해싱하여 생성된 것이 담김, 여기서 siganture를 복호화할 때 쓰는 비밀키가 서버에 저장되므로 비밀키가 유출되지 않는 이상 안전함

     

    하지만 토큰 자체를 탈취당하면 대처가 어렵기 때문에

    이를 위해 access token과 refresh token이라는 개념을 도입하였음

    클라이언트에 access token과 refresh token을 주고

    Access token의 기간을 짧게 설정, 만료되면 서버에 refresh token을 보내어 access token 재발급 요청

    이 경우 토큰이 탈취당하더라도 서버에서 refresh token을 강제로 만료시킬 수 있으므로 더욱 안전한 방법임

     

    https://tecoble.techcourse.co.kr/post/2021-05-22-cookie-session-jwt/



    <Axios로 요청하는 이유가 있나요? (fetch, Jquery 기반 AJAX도 있는 와중에)>

     

    axios는 브라우저와 node.js를 위한 비동기 HTTP 통신 라이브러리이며 Promise 기반이기 때문에 데이터를 다루기 편리함,

    또, 구형 브라우저를 지원하며 크로스 브라우징에 더욱 신경썼다는 특징이 있음

    라이브러리를 별도로 설치해야한다는 점 외에는 좋은 선택지라고 생각함

     

    Ajax는 promise기반이 아니며 fetch는 데이터를 실어 보낼 때 JSON 형식으로 변환해주어야 하는 번거로움이 있음.

    (+Fetch의 경우 내장함수이기 때문에 React Native와 같이 업데이트가 잦은 경우에도 잘 작동된다는 것이 장점이지만 현재 React Native는 쓰지 않음.)

    cf) promise는 자바스크립트의 비동기처리에 사용되는 객체, pending(대기, 비동기 처리가 실행되지 않은 상태),fulfilled(이행, 비동기처리가 완료되어 결과값 반환), rejected(실패, 비동기처리에 실패하여 오류가 발생한 상태), 한 작업이 끝나면 그다음 작업이 끝나도록 해줌 (ex: get요청 시 데이터를 받아오지도 않았는데 결과를 보여주는 오류를 막아줌)

    https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

     

    <실시간 채팅/화상채팅에는 왜 socket.io를 사용하나요?>

     

    이유를 요약하자면)

    실시간 채팅이기에 실시간 양방향 통신이 필요해서

    Websocket에 비해 여러 브라우저에서 잘 작동되어서

    채팅방을 구현할 때 특정 room에 있는 유저에게만 보내는 기능이 필요해서

    화상채팅 전 시그널링 작업이 필요해서

    Websocket 기능을 더 쉽게 쓸 수 있어서

     

    Socket.IO란 이벤트 기반으로 서버와 브라우저 간의 실시간 양방향 통신을 돕는 라이브러리로써 Websocket을 쉽게 쓰기 위해 사용한다. http는 일반적으로 양방향 통신이 불가능한데, polling, long-polling, WebSocket 등의 시스템 디자인을 사용하여 양방향 통신이 가능한 것처럼 구현할 수 있다. Socket.IO는 Websocket 기반이지만 HTTP long-polling도 지원하기에 websocket이 돌아가지 않는 브라우저 환경에서도 작동한다. (이런 것을 fallback이 있다고 함)

     

    또한 Socket.IO에는 namespace와 room이라는 기능이 있다. 하나의 socket 연결은 하나의 namespace를 가지며, 하나의 namespace 안에는 여러가지 room을 생성할 수 있다. 하나의 room 안에는 특정 클라이언트들을 join 하거나 leave 시킬 수 있으며, 한 클라이언트가 메시지를 보내는 등 이벤트를 발생시켰을 때 특정 room에 있는 클라이언트들에게만 이벤트를 emit하여 채팅방과 같은 기능을 구현할 수 있게 된다.

     

    Socket.io는 채팅 뿐만아니라 화상채팅을 위한 peer간 시그널링 작업에도 쓰일 수 있다. 각각의 유저 디바이스의 위치를 확인하고

    미디어 포맷에 대한 협의를 거쳐야 하는데 socket.io가 이를 가능하게 해주는 것이다.

     

    cf)

    polling 방식에서는 클라이언트에서 주기적으로 서버에 데이터를 요청한다. 클라이언트에서 요청이 오면 서버에서는 변경이 없거나 새로운 데이터가 없더라도 응답을 보낸다. 따라서 주기적으로 정해진 시간마다 데이터를 확인해야 하는 서비스에 적합할 수 있지만, 불필요한 요청이 많아질 수 있으므로 오버헤드가 과도하게 발생될 수 있다.

     

    long-polling 방식에서는 클라이언트에서 요청을 보내면 서버에서는 이벤트가 발생했을 때 응답을 보낸다. 서버에서 변경 사항이 있을 때에만 응답을 보내기 때문에 polling 방식보다 불필요한 요청이 덜 발생하게 되지만, long-polling 방식에서도 클라이언트가 서버 응답을 무한정 기다리지는 않는다. 일정 시간이 지나면 새로운 요청을 보내는 방식이다. 서버에서 응답을 받았을 때는 클라이언트가 즉시 요청을 다시 보내면서, 마치 영구적인 연결이 이뤄진 것 처럼 구현된다.

     

    WebSocket 방식에서는 클라이언트가 요청을 최초 한 번만 보낸다. 재요청을 보내지 않아서 오버헤드가 적고 효율적일 수 있지만, 필요 이상으로 연결을 오래 유지할 경우 서버 CPU에 부담이 되는 등의 단점이 발생할 수 있다.

     

    cf) 오버 헤드는 특정 기능을 수행하는데 드는 간접적인 시간, 메모리 등 자원을 말한다.

     

    https://velog.io/@kskim625/Socket.IO%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90



    ▶ 느낀 점

     

    프로젝트를 한번 되돌아보는 시점이었다.

    아직 프로젝트의 전체 그림을 완전히 이해하기에는 공부가 더 필요하다는 것을 알게 되었다.

    또한 어떤 기술을 사용할 때에 무엇이 문제였으며 어떻게 해결하였고 왜 그런지에 대한 정리를

    기록하는 습관, 또는 그렇게 접근 하는 사고 방식을 길러보면 좋겠다. (what?, why?, How?)

    그리고 그것을 시각화해서 보여줄 수 있다면 더욱 쉽게 전달하고 내 역량을 어필할 수 있을 것이다.

    또한 어떤 기술 사용에 제약이 있더라도 그것을 프로그래머 본인의 역량으로 해결해나가는 것이 있다면 굉장한 플러스 요소이다.

    (ex: 지도의 거리를 계산할 때 여러 라이브러리를 사용해 봤지만 실패함 => 좌표간 거리를 계산하는 식을 직접 만들어서 사용)

     

    다른 팀원들을 보니 다들 매우 잘하고 있다.

    나도 그분들 못지 않게 열심히 달려나가보자.

    떄론 막막하고 어려워 보여도 끊임없이 시도해보고 개선해나간다면 결국엔 해낼 것이다 :)

    (말해놓고 보니 마치 애자일 방식같다. 프로그래밍을 하면서 삶을 대하는 태도가 달라지는 느낌인데 이것도 그 중 하나이려나..? ㅎㅎ)

     

     

    ▶ 공부 시 참고 링크들

     

    https://hanamon.kr/redux%EB%9E%80-%EB%A6%AC%EB%8D%95%EC%8A%A4-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/

     

    Redux(리덕스)란? (상태 관리 라이브러리) - 하나몬

    Redux(리덕스)란? 무엇인지 부터 간단한 실습까지 (상태 관리 라이브러리 리덕스 알아보기) ⚡️ Redux(리덕스)란? Redux(리덕스)란 JavaScript(자바스트립트) 상태관리 라이브러리이다. Redux(리덕스)의

    hanamon.kr

    https://kyun2da.dev/%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC/Redux-%EC%A0%95%EB%A6%AC/

     

    Redux 정리

    Redux란? 리덕스는 리액트에서 가장 많이 사용되는 상태 관리 라이브러리중 하나이다. 리덕스를 사용하면 컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리시켜서 효율적으로 관리할 수

    kyun2da.dev

     

    https://mingoogle.tistory.com/12

     

    [ 조각모음 ] - squelize의 장단점과 package-lock.json

    안녕하세요. 이번 글은 시퀄 라이즈와 package-lock.json에 대하여 포스팅하고자 합니다. 나중에 sequelize와 package.json에 관한 포스팅을 하게 되면 따로 분리할 예정입니다. 참고: package.json npm을 가지고

    mingoogle.tistory.com

    https://ljtaek2.tistory.com/142

     

    자바스크립트 - 동기(Synchronous)? 비동기(asynchronous)?

    들어가기 전에, 필자는 자바스크립트를 처음 접하고, 오로지 문법적인 것에만 집중해서 공부를 했었다. 하지만 개발할 때 더 중요한 것은 자바스크립트가 어떻게 동작하는지를 먼저 알고 개발

    ljtaek2.tistory.com

     

    '항해 99' 카테고리의 다른 글

    항해 99 5기 TIL_70  (0) 2022.03.20
    항해 99 5기 TIL_69  (0) 2022.03.20
    항해 99 5기 TIL_67  (0) 2022.03.18
    항해 99 5기 TIL_66  (0) 2022.03.17
    항해 99 5기 TIL_65  (0) 2022.03.16
Designed by Tistory.