1. 웹소켓 기술  

  • 전이중 통신 - 실시간성 보장하는 서비스 (채팅, 게임, 주식거래 사이트 등)에 주로 사용
  • HTTP에도 실시간성 보장하는 기법이 존재하지만, 서버에 부하가 많이 가기 때문에 웹소켓을 이용한다.
  • HTTP는 비연결성 프로토콜, 단방향성 통신이다. 따라서 매번 연결 맺고 끊는 과정의 비용이 든다.
  • 반면, 웹소켓은 연결지향이라 한번 연결 맺은 뒤 유지, 양방향 통신이다.
  • 보내야하는 메시지와 데이터 양에서도 차이가 난다. 웹소켓을 사용하면 HTTP와 비교했을 때 한번 통신한 후엔 훨씬 적은 양의 데이터로 통신해서 부담을 덜 수 있다. 

 

2. 웹소켓의 단점 : 모든 브라우저에서 허용되는 것은 아니다.

→ 이 문제를 SockJs 와 Socket.io 를 사용하여 해결 할 수 있다. (스프링은 SoketJs사용)

 

※ 스프링에서 웹소켓 설정은 아주 간단한다. 

  • 웹소켓 Config 파일 - addHandler 핸드쉐이크할 주소를 적어줌
  • 핸들러 부분 - 웹소켓 세션을 오버라이드해서 받아오는데, 웹소켓 연결정보를 담고 있는 세션이다.
  • Cors설정
  • .withSockJS() 를 통해 라이브러리 사용 가능.

 

3. Stomp 프로토콜

  • 메시지 브로커를 활용하여 쉽게 메시지를 주고 받을 수 있는 프로토콜
  • 웹소켓 위에 얹어 함께 사용할 수 있는 하위 프로토콜 
  • 메시지 브로커랑 발신자의 메시지를 받아와 수신자들에게 메시지를 전달하는 어떤 것 !

그렇다면 왜 이게 필요한가 ?

프레임 단위 ( 커맨드, 헤더, 바디 ) 의 형태로 메시지 형태를 정해줌. - 컨벤션을 따로 정의할 필요 없다.

 

 

https://www.youtube.com/watch?v=rvss-_t6gzg 

 

Message Broker란?

  • Publisher로부터 전달받은 메세지를 Subscriber로 전달해줄 때 중간에서 메세지를 주고 받게 해주는 중간 역할

https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/html/websocket.html

 

26. WebSocket Support

This part of the reference documentation covers Spring Framework’s support for WebSocket-style messaging in web applications including use of STOMP as an application level WebSocket sub-protocol. Section 26.1, “Introduction” establishes a frame of m

docs.spring.io

 

In Memory Broker란?

  • Spring websocket에서 STOMP 프로토콜을 사용해서 웹소켓 기능을 구현할 때 STOMP는 Message Broker가 필요하다.
  • 이 때 아무 설정 없이 Spring 환경에서 STOMP 프로토콜을 사용한다면 메세지 브로커로 In Memory Broker를 사용하게 된다.

 

그렇다면 하나의 서비스를 만들 때 In Memory Broker를 메세지 브로커로 사용해도 상관 없을까?

상관있다... 아래를 보면, In Memory 브로커의 단점들이 존재한다.

  1. 세션을 수용할 수 있는 크기가 제한되어 있다.
  2. 장애 발생 시 메세지의 유실될 가능성이 높다.
  3. 따로 모니터링하는 것이 불편하다.

 

그렇다면 In Memory 브로커 대신 무슨 브로커를 사용할 수 있을까?

  • RabbitMQ, ActiveMQ 등에서는 STOMP 프로토콜의 Message Broker 기능을 제공해준다. 
  • 따라서 이들의 힘을 빌려 In Memory 브로커 대신 잘 만들어진 STOMP 전용 외부 브로커를 사용하는 것이 더 좋다.

 

STOMP 전용 외부 브로커를 사용하는 장점이 무엇이 있을까?

  1. 확장성 : 세션을 수용할 수 있는 크기가 크다.
  2. 결함 허용성 : 영구적이며 문제가 발생했을 시 재시도가 가능하여 복구가 가능하다.
  3. 모니터링 : 간편하게 모니터링을 할 수 있다.

 


[ 참고자료 ]

 

https://withseungryu.tistory.com/137

 

WebSocket은 클라이언트 서버간 양방향 통신이 가능하지만, 다음과 같은 이슈가 있다.
1. websocket미지원 웹 브라우저가 있다는 점
2. 웹 브라우저 이외의 클라이언트 지원(서버 입장에서는 클라이언트는 웹 브라우저뿐만이 아님)


WebSocket

  • WebSocket 동작 순서

 

 

  • Http의 특징 중 하나는 단방향 통신이다.
    클라이언트와 서버간의 통신은 단건으로 이루어지며 하나의 요청(통신)이 끝나게 되면 클라이언트와 서버는 아무런 관계가 없어지게된다. 이 말은 서버입장에서 클라이언트로부터 요청이 있기전까지는 어떤 데이터도 전송할 수 없다는 것이다.
    이런 문제를 해결하기 위해 양방향 통신이 생겨나게 되었고, WebSocket으로 구현하게 되었다.
  • WebSocket은 Http를 통해 작동하도록 설계되었으며, Http Header에 특정 값("websocket")을 명시함으로써 WebSocket 프로토콜로 전환하는 요청으로 시작된다.

 

STOMP 

  • 스트리밍 텍스트 지향 메시지 프로토콜
  • STOMP는 Simple/Stream Text Oriented Message Protocol의 약자로, 메시지 브로커의 역할을 한다.
  • 메시지 전송을 효율적으로 처리하기 위한 프로토콜
  • STOMP는 WebSocket 기반으로 동작하며 pub/sub 구조로 되어 있다. pub/sub 구조는 쉽게 말해 편지를 쓰는 사람(Publisher)이 편지함에 편지를 넣어두면 그걸 기다리고 있던 편지를 받는 사람(Subscriber)이 편지를 받고 읽는 구조이다.
  • 즉, WebSocket 위에서 동작하는 프로토콜로써 클라이언트와 서버가 전송할 메시지의 유형, 형식, 내용들을 정의하는 메커니즘이다.

 

Stomp를 사용하는 이유

  • STOMP 를 사용하여 WebSocket만 사용할 때보다 더 다채로운 모델링을 할 수 있다.
  • Messaging Protocol을 만들고 메세지 형식을 커스터마이징 할 필요가 없다.
  • RabbitMQ, ActiveMQ 같은 Message Broker를 이용해, Subscription(구독)을 관리하고 메세지를 브로드캐스팅할 수 있다.
  • WebSocket 기반으로 각 Connection(연결)마다 WebSocketHandler를 구현하는 것 보다 @Controller 된 객체를 이용해 조직적으로 관리할 수 있다.
  • 즉, 메세지는 STOMP의 "destination" 헤더를 기반으로 @Controller 객체의 @MethodMapping 메서드로 라우팅 된다.
  • STOMP의 "destination" 및 Message Type을 기반으로 메세지를 보호하기 위해 Spring Security를 사용할 수 있다.

 

SockJS

  • WebSocket은 upgrade Header를 이용하여 Socket연결을 하고, 통신을 진행한다. 이 과정에서 여러가지 이유로 소켓연결이 불가능하게 될 경우가 있는데 이럴 경우 Http기반의 다른 기술로 전환하여 다시 연결을 시도해야할 필요가 있다. 이 때 사용하시는 것이 'WebSocket Emulation'이다. 그리고 Spring에서는 Emulation을 위해 'SockJS' 라이브러리를 지원한다.
  • SockJS는 다양한 기술을 이용해 웹소켓을 지원하지 않는 브라우저에서 정상 작동하도록 도와주는데.
  1. WebSocket
  2. HTTP Streaming
  3. HTTP Long Polling
    세가지 타입을 이용한다.

 

Redis 

레디스(Redis)는 Remote Dictionary Server의 약자로서, "키-값" 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형 데이터베이스 관리 시스템(DBMS)이다.

 

redis를 사용하는 이유?

1.놀라울 정도로 빠른 성능

Redis와 같은 인 메모리 데이터베이스는 디스크에 액세스해야 할 필요를 없앰으로써 검색 시간으로 인한 지연을 방지하고 CPU 명령을 적게 사용하는 좀 더 간단한 알고리즘으로 데이터에 액세스할 수 있다.

 

2. 인메모리 데이터 구조

Redis를 사용하면 사용자가 다양한 데이터 유형에 매핑되는 키를 저장할 수 있다.

 

3. 다양성과 사용 편의성

Redis는 개발과 운영을 좀 더 쉽고 좀 더 빠르게 수행할 수 있는 여러 가지 도구를 제공한다. Pub/Sub는 메시지를 채널에 게시하며, 채널에서 구독자에게 전달된다. 채팅과 메시징 시스템에 매우 적합하다.

 

4. 복제 및 지속성

Redis는 마스터-슬레이브 아키텍처를 사용하며 비동기식 복제를 지원하여 데이터가 여러 슬레이브 서버에 복제될 수 있다. 이렇게 하면 주 서버에 장애가 발생하는 경우 요청이 여러 서버로 분산될 수 있으므로 향상된 읽기 성능과 복구 기능을 모두 제공할 수 있다.

 

5. 선호하는 개발 언어 지원

Redis 개발자는 백 개가 넘는 오픈 소스 클라이언트를 사용할 수 있으며, Java, Python, PHP, C, C++, C#, JavaScript, Node.js, Ruby, R, Go를 비롯한 다수의 언어가 지원된다.

 

※ Redis 다운로드

https://github.com/microsoftarchive/redis/releases

 


[ 정리 ]

  • Websoket을 사용하려면 메시지 브로커 역할을 해주는 Stomp와 웹소켓을 지원하지 않는 브라우저에서 작동하도록 도와주는 SockJS 라이브러리를 같이 사용해야 한다.
  • Stomp broker 설정으로만 채팅이 되는 것이 아니다. 클라이언트가 서로 다른 서버에 연결이 됬을때 채팅을 하려면 Redis가 필요하다.
  • 메시지 브로커 사용하는 이유는 3가지
    • 서비스(어플리케이션) 간의 의존성 제거
    • 메시지 처리 시점
    • 다양하고 유연한 통신

[ 참고자료 ]

 

https://fgh0296.tistory.com/24

 

sockJS와 stompJS

필자는 팀 프로젝트에서 채팅서비스를 도입하여 온라인에서 사용자끼리 상품 거래를 할 수 있도록 클라이언트에서 공부해야 할 기술 스택을 찾고 있다가 sockJS를 알게 되었다. 그리고 다음과 같

fgh0296.tistory.com

https://velog.io/@koseungbin/WebSocket

 

WebSocket

이 글은 Spring WebSocket(https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web.htmlWebSocket 프로토콜은 표준된 방법으로 서버-클라이언트 간

velog.io

https://thdwngus2.tistory.com/100

 

spring stomp, redis 적용하기

배운점 stomp 적용하기 stomp란? 메시지 전송을 효율적으로 하기 위해 나온 프로토콜이며 기본적으로 pub/sub 구조로 되어있어 메시지를 발송하고, 메시지를 받아 처리하는 부분이 확실히 정해져 있

thdwngus2.tistory.com

 

실전프로젝트에 실시간 채팅과 음성 채팅 기능을 구현해야 한다.

Spring 채팅기능에 관련해 찾아보니 WebSocket과 WebRTC 두가지 키워드가 등장했다. 

다음은 WebSoket과 WebRTC에 대한 간략한 정리이다.


WebRTC vs WebSockets: What are the key differences?

  • WebSocket provides a client-server computer communication protocol, whereas WebRTC offers a peer-to-peer protocol and communication capabilities for browsers and mobile apps.
  • While WebSocket works only over TCP, WebRTC is primarily used over UDP (although it can work over TCP as well).
  • WebSocket is a better choice when data integrity is crucial, as you benefit from the underlying reliability of TCP. On the other hand, if speed is more important and losing some packets is acceptable, WebRTC over UDP is a better choice.
  • WebRTC is primarily designed for streaming audio and video content. It is possible to stream media with WebSockets too, but the WebSocket technology is better suited for transmitting text/string data using formats such as JSON.

 

TCP와 UDP의 차이점은 ?

  • TCP는 연결 지향 프로토콜인 반면 UDP는 비연결 프로토콜입니다. TCP가 UDP보다 비교적 느리기 때문에 TCP와 UDP의 주요 차이점은 속도입니다. 전반적으로 UDP는 훨씬 빠르고 간단하며 효율적인 프로토콜이지만 손실된 데이터 패킷의 재전송은 TCP를 통해서만 가능합니다. 
  • TCP와 UDP의 또 다른 주목할 만한 차이점은 TCP는 사용자에서 서버로(또는 그 반대로) 데이터를 순서대로 전달하는 반면 UDP는 종단 간 통신 전용이 아니며 수신자의 준비 상태를 확인하지도 않는다는 것입니다.  

 

When to use WebRTC?

WebRTC is a good choice for the following use cases:

  • Audio and video communications, such as video calls, video chat, video conferencing, and browser-based VoIP.
  • File sharing apps.
  • Screen sharing apps.
  • Broadcasting live events (such as sports events).
  • IoT devices (e.g., drones or baby monitors streaming live audio and video data).

 

When to use WebSockets?

We can broadly group Web Sockets use cases into two distinct categories:

  • Realtime updates, where the communication is unidirectional, and the server is streaming low-latency (and often frequent) updates to the client. Think of live score updates or alerts and notifications, to name just a few use cases.
  • Bidirectional communication, where both the client and the server send and receive messages. Examples include chat, virtual events, and virtual classrooms (the last two usually involve features like live polls, quizzes, and Q&As). WebSockets can also be used to underpin multi-user synchronized collaboration functionality, such as multiple people editing the same document simultaneously.

 

[ 정리 ]

  • WebSocket은 데이터 무결성이 중요한 경우 TCP의 기본 안정성을 활용하므로 더 나은 선택
  • 반면에 속도가 더 중요하고 일부 패킷 손실이 허용되는 경우 UDP를 통한 WebRTC가 더 나은 선택

 

[ 결론 ] : 두 가지 모두 사용 ?

WebSocket : 게임과 채팅 구현을 위해 실시간성을 보장하는 통신 방식. HTTP에서도 실시간성을 보장하는 반이중 기법들(polling, long polling, streaming)이 존재하나, 실시간성이 떨어지거나 서버 부하가 올라갈 수 있다는 단점이 있어서, 하나의 TCP 연결을 통해 양방향 통신을 제공하는 Websocket을 선택.

 

WebRTC : 화상/보이스 채팅 기능을 위해 카메라와 마이크 등의 미디어 자원을 통해 실시간으로 소통할 수 있는 기술이 필요. WebRTC는 브라우저에서 지원하는 프레임워크로 많이 사용되어 안정성이 검증되어있고, 별도의 플러그인 없이 사용이 가능하여 User 경험에 유리하다.

 

이번 프로젝트땐 아마 일반 채팅엔 WebSocket을, 그리고 화상/음성 채팅엔 WebRTC를 사용할 것 같다 : ) 


[ 참고자료 ]

https://ably.com/topic/webrtc-vs-websocket

 

WebRTC vs. WebSocket: Which one is the right choice for your use case? | Ably Realtime

We compare WebRTC with WebSocket. Discover how they are different, their pros & cons, and their use cases.

ably.com

https://www.lifesize.com/blog/tcp-vs-udp/

 

TCP vs. UDP: What’s the Difference?

In the world of Internet protocol traffic, consumers can choose between a TCP or UDP setup for their business or personal use. When it comes to TCP vs UDP features and functions, each brings its own set of advantages and challenges. With that said, UDP is

www.lifesize.com

 

Optional<> vs List<>

  • Optional은 null 또는 값을 감싸서 NPE(NullPointerException)로부터 부담을 줄이기 위해 등장한 Wrapper 클래스이다. 
  • Optional은 값을 Wrapping하고 다시 풀고, null 일 경우에는 대체하는 함수를 호출하는 등의 오버헤드가 있으므로 잘못 사용하면 시스템 성능이 저하된다.
  • 그렇기 때문에 메소드의 반환 값이 절대 null이 아니라면 Optional을 사용하지 않는 것이 좋다. 즉, Optional은 메소드의 결과가 null이 될 수 있으며, null에 의해 오류가 발생할 가능성이 매우 높을 때 반환값으로만 사용되어야 한다.
  • Optional은 반환 타입으로써 에러가 발생할 수 있는 경우에 결과 없음을 명확히 드러내기 위해 만들어졌으며, Stream API와 결합되어 유연한 체이닝 api를 만들기 위해 탄생한 것이다. 예를 들어 Stream API의 findFirst()나 findAny()로 값을 찾는 경우에 어떤 것을 반환하는게 합리적일지 Java 언어를 설계하는 사람이 되어 고민해보자. 언어를 만드는 사람의 입장에서는 Null을 반환하는 것보다 값의 유무를 나타내는 객체를 반환하는 것이 합리적일 것이다. Java 언어 설계자들은 이러한 고민 끝에 Optional을 만든 것이다. 그러므로 Optional이 설계된 목적에 맞게 반환 타입으로만 사용되어야 한다.

 

https://mangkyu.tistory.com/203

http://www.tcpschool.com/java/java_stream_optional

 

Null vs isEmpty() 차이

Null

  • 인스턴스가 생성되지 않은 상태이다.
  • List 변수가 메모리에 아무런 주소값도 참조하지 않은 상태이다.
  • 변수에 아무것도 할당되지 않은 상태를 의미한다.

isEmpty

  • size() = 0
  • Java SE 1.6 이상부터 사용이 가능하다.
  • 배열이 생성되었으나, 배열안에 아무것도 없는 상태를 말한다.
  • 객체는 존재하지만, 공백이다.
  • 변수에 문자열값이 할당되었지만, 그 길이가 0임을 의미한다. 

 

※ Null string은 언제나 비어있지만, Empty string은 null이 아닐 수도 있다.

 

http vs https

  • HTTPS(https://)는 SSL(Secure Socket Layer) 인증서를 사용하는 HTTP(http://)입니다. SSL(또는 TLS) 인증서는 일반 HTTP 요청 및 응답을 암호화합니다. 따라서 HTTPS는 HTTP보다 더 안전한 보안용 프로토콜이라고 할 수 있습니다.
  • HTTP와 HTTPS의 유일한 차이점은 HTTPS를 사용한 웹 페이지를 통해 전송되는 모든 데이터는 추가적인 보안 계층이 있습니다. 이를 TLS(전송 계층 보안) 프로토콜이라고 합니다. 모든 유형의 데이터는 변경되거나 손상될 수 없는 HTTPS 사이트를 통해 전달되며 제3자로부터 보호됩니다.

 

※ HTTPS 확인 방법 : 도메인 이름 앞에 자물쇠 아이콘이 있으면 당신의 사이트는 HTTPS로 인해 안전한 것입니다.

 

지연로딩 vs 즉시로딩 (FetchType.LAZY or EAGER)

  • JPA에서는 데이터를 조회할 때 즉시 로딩(EAGER)과 지연 로딩(LAZY) 두 가지 방식이 있다.
  • 이 두 가지 방식을 간단하게 설명하면 즉시 로딩은 데이터를 조회할 때 연관된 데이터까지 한 번에 불러오는 것이고, 지연 로딩은 필요한 시점에 연관된 데이터를 불러오는 것이라고 할 수 있다.

  • 비지니스 로직 상 Member 데이터가 필요한 곳에 대부분 Team의 데이터 역시 같이 사용 할 필요가 있다면 어떨까? FetchType을 EAGER로 설정하여 항상 Member와 Team을 같이 조회해오는 것이 더 좋을 것이다.
  • Member를 사용하는 곳 대부분에서 Team 데이터가 필요하지 않다면? FetchType을 LAZY로 설정하여 Member만 조회하고, 드물게 Team이 필요할 땐 그 때 Team에 대한 쿼리를 한번 더 날려 조회하는것이 좋을 것이다.

※ 실무에서는 EAGER LOADING을 사용하지 않는 것을 권장한다. 

 

이유는?

즉시 로딩에서는 Member와 연관된 Team이 1개여서 Team을 조회하는 쿼리가 1개 나갔지만, 만약 Member를 조회하는 JPQL을 날렸는데 연관된 Team이 1000개라면? Member를 조회하는 쿼리를 하나 날렸을 뿐인데 Team을 조회하는 SQL 쿼리 1000개가 추가로 나가게 된다. 그렇기 때문에 가급적이면 기본적으로 지연 로딩을 사용하는 것이 좋다.

 

https://developer-hm.tistory.com/37

https://ahndding.tistory.com/24

 

UTF파일 인코딩

UTF-8

  • UTF는 Unicode Transformation Format의 줄임말로 전세계 모든 문자를 컴퓨터에서 표현하고 다룰 수 있도록 설계된 산업표준이다.
  • 따라서 한글도 당연하게 표현가능하다.
  • UTF-8은 문자열 집합과 인코딩 형태를 8bit단위로 한다는 의미를 가진다.
  • UTF-8은 한 글자를 표현하기 위해 1~4byte를 사용하는데 이를 가변길이 인코딩 방식이라고 한다.

ANSI

  • ANSI는 ASCII의 확장이라고 할 수 있다.
  • ANSI는 8bit로 이루어져 있어서 256개의 문자를 표현할 수 있다.
  • 하지만 ANSI로 모든 언어를 표현할 수 없어서 Code Page라는 개념이 도입되었다.
  • 각 언어별로 Code 값을 지정하고, Code마다 다른 문자열 표를 의미하도록 약속을 한 것이다.

CP949

  • CP949는 ANSI계열의 한글 인코딩 방식이다.
  • CP949는 Code Page 949의 줄임말이고, 949는 한국을 의미한다.
  • 유닉스계열의 완성형 코드 조합 인코딩방식인 EUC-KR을 확장하여 만든것이다.
  • EUC-KR로는 표현할 수 있는 문자에 한계가 있었기 때문이다.
  • CP949는 윈도우즈 계열에서 사용나온것이고, 마이크로소프트가 EUC-KR을 확장하여 만든것이라서 MS949라고 부르기도 한다.

https://velog.io/@ovan/File-Encoding

 

+ Recent posts