WebRTC 알아보기

목표 WebRTC가 무엇인지 이해한다. WebRTC의 전체적인 구조를 이해한다. WebRTC 통신을 하기 위한 전체적인 과정을 이해한다. WebRTC란? WebRTC는 P2P 통신을 지원해주는 웹 표준이다. 오픈소스이기 때문에 지속적으로 발전되고 있다. 대부분의 최신 브라우저에서 사용가능하다. 브라우저뿐만아니라 모바일 애플리케이션에서도 사용가능하다. WebRTC는 주로 음성, 영상 통화에서 사용되고 그 뿐만 아니라 다양한 데이터를 전달할 때 사용할 수 있다. 서버를 통해 데이터를 받아야되는 WebSocket과 달리, P2P 통신으로 이루어지기 때문에 서버 과부하 문제를 해결할 수 있고, 개인 정보 보호의 이점도 가지고 있다....

2024-09-15 · 2 min · 215 words

WebRTC API 시작하기

WebRTC를 사용하기 위해서 JavaScript로 제공하고 있는 API들을 알아본다. 크게 두 기지 기능으로 나눌 수 있다. P2P 연결: 두 피어 간의 연결 설정 및 제어. WebRTC에 해당하는 영역. 미디이 캡쳐 기기: 동영상 카메라, 마우스, 화면 캡처 등. WebRTC를 사용하기 위해 함께 자주 사용되는 WebAPI P2P 연결 기본적으로 RTCPeerConnection 인터페이스에서 처리한다. P2P 연결이 진행되기 위해서는 Signaling이라는 과정이 필요하다. Signaling WebRTC에서는 다양한 데이터를 전송할 수 있기 때문에, 전송할 데이터 형식을 피어 간에 공유해야된다. 이렇게 전송 할 데이터의 형식과 상대 피어의 위치를 알아내는 과정을 signaling이라고 부른다....

2024-09-15 · 3 min · 573 words

webpack에서 오류 발생시 화면 가리지 않도록 하기

배경 webpack에서는 기본적으로 오류가 발생하면 화면을 가려서 사용하지 못 하도록한다. 빠른 개발을 위해서 이를 비활성화 하기 위해서 아래와 같은 설정을 했지만 적용되지 않았다. vue.config.js module.exports = { devServer: { overlay: false, }, }; 문제 해결 webpack 버전이 올라가면서 사양이 바뀌었다. vue.config.js module.exports = { devServer: { client: { overlay: false, }, }, }; vue.config.js 파일은 vue-cli에서 프로젝트에서 webpack에 대한 설정을 추가할 수 있기 때문에 webpack.config.js를 사용하지 않아도 된다. 따라서, vue-cli보다 webpack 문서를 읽어보는 것이 더 정확하다....

2024-09-15 · 1 min · 81 words

WebMvcConfigurer

WebMvcConfigurer 를 구현하면, WebMvc의 설정을 할 수 있다. addViewControllers 를 통해 정적인 웹을 url에 매핑 시킬 수 있다. @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("home"); } } addInterceptors 를 통해 오는 요청에 인터셉트를 할 수 있다. @Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LocaleChangeInterceptor()); registry.addInterceptor(new ThemeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**"); registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*"); } } addArgumentResolvers를 통해 커스텀 어노테이션을 인자로 매핑시킬 수 있다....

2024-09-15 · 1 min · 134 words

WebFlux 기초 이해하기

목표 리액티브 프로그래밍을 이해한다. Spring WebFlux 내부 동작 방식을 이해한다. 리액티브 프로그래밍 리액티브 프로그래밍 비동기 이벤트 처리와 데이터 스트림에 대한 아이디어를 기반으로 한다. 비동기 이벤트 처리는 다른 이벤트 처리를 차단하지 않는다는 것을 의미한다. 이벤트 큐와 병렬 이벤트 처리를 도입하여 성능과 확장성을 향상시킨다. 기본적으로 리액티브 프로그래밍은 3가지 구성요소를 가진 옵저버 패턴이다.(RxJava 기준) Observable: 데이터 스트림을 표현한다. 한 스레드에서 다른 스레드로 전달할 수 있는 데이터를 담는다. Observer: Observable이 방출하는 데이터 스트림을 소비한다. Observable이 데이터를 방출할 때마다 데이터를 통해 작업을 수행하거나 예외를 던진다....

2024-09-15 · 3 min · 509 words

WebClient로 URL parameter 보내기

목표 Spring 에서 제공하는 WebClient로 HTTP 요청을 보낼 때, URL parameter를 전송하는 방법을 알아본다. parameter 보내기 webClient.get() .uri(uriBuilder - > uriBuilder .path("/products/") .queryParam("name", "{name}") .build("asdf+asdf")) .retrieve() .bodyToMono(String.class) .onErrorResume(e -> Mono.empty()) .block(); 위와 같이 작성하면 /products?name=asdf%2asdf 로 요청이 보내지는 것을 확인할 수 있다. 주의점 아래와 같이 쿼리 파라미터를 넘기면 예상치 못한 방식으로 URL 인코딩이 될 수 있기 때문에 주의해야된다. 아래와 같이 요청을 보내면 ‘+’ 문자가 URL 인코딩 되지 않고 요청이 보내진다. /products%3Fname=asdf+asdf 반대로 ‘?...

2024-09-15 · 1 min · 168 words

WAS에서 IP 차단 체크할 때, 웹 서버 IP 확인하는 문제 해결

HTTP 요청을 보낸 사람의 IP를 확인해서 DB에 등록되어 있는 사용자만 허가되도록 구현했다. 하지만 WAS가 HTTP를 받았을 때 항상 IP가 웹 서버(NGINX)의 IP로 인식되는 문제가 있었다. 문제 해결 WAS는 중간에 있는 리버스 프록시의 IP를 인식하는 문제가 있었다. 보통 요청을 보낸 Client의 IP 를 확인하기 위해서 X-Forwarded-For 헤더를 사용한다고 한다. 이를 구현하기 위해서는 크게 2가지 작업이 필요했다. 리버스 프록시 서버인 NGINX 설정 변경 WAS에서 X-Forwarded-For 헤더를 확인하도록 수정 NGINX 설정 변경 nginx에서는 $proxy_add_x_forwarded_for 라는 변수를 제공한다....

2024-09-15 · 1 min · 163 words

vue-router에서 뒤로가기 구현 방법

목표 vue-router에서 뒤로가기 구현 방법을 이해한다. vue-router의 2가지 모드 hash mode url에 ‘#‘을 사용해서 URL이 변경되어도 페이지가 리로딩되지 않도록 하는 모드 history mode history.pushState를 사용해서 URL이 변경되어도 페이지가 리로딩되지 않도록 하는 모드 참고: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState 서버 설정에 따라, 404 에러가 발생할 수 있으므로 웹 서버 설정을 확인해봐야된다. 뒤로가기 구현법 this.$router.push: 히스토리 스택에 새로운 경로로 이동할 수 있다. this.$router.go: 히스토리 스택을 이동할 수 있다. // go forward by one record, the same as router....

2024-09-15 · 1 min · 105 words

vue-router로 컴포넌트 이동시 이전 컴포넌트 상태 유지

방법 <KeepAlive> 컴포넌트를 사용하면, 이전 컴포넌트의 상태를 캐싱했다가 뒤로돌아가도 유지된다. https://vuejs.org/guide/built-ins/keep-alive.html#basic-usage KeepAlive의 상태 유지 방법 KeepAlive 컴포넌트 레벨에서 캐싱이 이루어지고 있다. 만약 중간에 KeepAlive DOM이 사라지면 캐싱이 지워진다. https://github.com/vuejs/vue/blob/dev/src/core/components/keep-alive.js#L90 참고 자료 https://stackoverflow.com/questions/41764825/preserve-component-state-with-vue-router https://stackoverflow.com/questions/71145498/where-does-vuejs-store-the-cached-component-when-using-keep-alive

2024-09-15 · 1 min · 33 words

vue-router 파라미터 가져오기

방법 $route.params를 통해 가져올 수 있다. pattern matched path $route.params /users/:username /users/eduardo { username: ’eduardo’ } /users/:username/posts/:postId /users/eduardo/posts/123 { username: ’eduardo’, postId: ‘123’ } 참고 자료 https://router.vuejs.org/guide/essentials/dynamic-matching.html

2024-09-15 · 1 min · 27 words

VSCode에서 SSH 연결하기

VSCode로 SSH 환경에서 작업을 해야되는 상황이었다. 1. Remote Development 설치 VSCode에서 확장 프로그램을 설치 해야된다. 아래 경로에서 설치 가능하다. https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack 2. Config 파일 수정 config 파일을 수정해서 자신이 접속할 경로와 사용자명을 작성하면 된다. Windows 기준 아래의 경로에 파일이 존재한다. C:\Users\사용자명\.ssh\config 해당 파일의 다음과 같은 파일 형식으로 지정해두면 이후에 쉽게 접속이 가능해진다. 아래 예시는 pem 키를 이용해서 접속하는 경우다. pem키를 사용하지 않고 사용지 비밀번호를 입력하는 경우는 4번 라인의 IdentityFile 을 제거하면된다....

2024-09-15 · 1 min · 75 words

verify

목표 mockito의 verify() 메서드를 통해 검증할 수 있는 내용들을 알아본다. 호출된 횟수 검증 List<String> mockedList = mock(MyList.class); mockedList.size(); verify(mockedList, times(1)).size(); 호출되지 않음을 검증 List<String> mockedList = mock(MyList.class); mockedList.size(); verify(mockedList, never()).clear(); 호출되는 인자 매칭 커스터마이징 인자 매칭 기준이 복잡하다면 ArgumentMatchers.argThat() 을 통해서 매칭 기준을 커스터마이징할 수 있다. 인자로 ArgumentMatcher라는 함수형 인터페이스를 받고 있어서 람다로 구체적인 조건을 명시할 수 있다. 참고 자료 https://www.baeldung.com/mockito-verify https://www.baeldung.com/mockito-argument-matchers

2024-09-15 · 1 min · 62 words

UsingRecursiveFieldByFieldElementComparator 사용시 일부 필드는 제외하는 방법

assertThat(actual) .usingRecursiveFieldByFieldElementComparator() .usingElementComparatorIgnoringFields("field_1", "field_2") .isEqualTo(expected) 참고 자료 https://issueexplorer.com/issue/assertj/assertj-core/2263

2024-09-15 · 1 min · 8 words

useEffect 사용법

목표 useEffect 사용법을 이해한다. useEffect Effect는 특정 이벤트가 아닌 렌더링에 의해 발생한 사이드 이펙트를 명시할 수 있다. 채팅에서 메시지를 보내는 것은 사용자가 특정 버튼을 클릭함으로써 직접 발생하므로 이벤트다. 서버 연결은 컴포넌트가 표시되는 유저와의 상호작용과 관계 없이 발생해야 되므로 이펙트다. Effect는 외부 시스템과 동기화할 때 사용하면 좋다. 렌터링 될 때마다 실행하기 function MyComponent() { useEffect(() => { // Code here will run after *every* render }); return <div />; } Effect의 의존성 명시하기 모든 렌더링에 대해서 실행되지 않아야되는 경우가 있다....

2024-09-15 · 1 min · 196 words

URL에 파라미터 사용하기

url에 유동적으로 바뀌는 부분이 있다면 파라미터를 사용하여 처리할 수 있다. RestAssured.given() .when() .get("http://restcountries.eu/rest/v1/name/{country}", cty) .then() .body("capital", containsString("Helsinki")); 참고 자료 https://stackoverflow.com/questions/32475850/how-to-pass-parameters-to-rest-assured

2024-09-15 · 1 min · 20 words

Url Encoding, Decoding 하기

URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); URLDecoder.decode(value, StandardCharsets.UTF_8.toString()); https://www.baeldung.com/java-url-encoding-decoding

2024-09-15 · 1 min · 5 words

UnaryOperator T 함수형 인터페이스

T를 인자로 받고 T를 반환한다.

2024-09-15 · 1 min · 5 words

Type을 만족하는 모든 Bean 주입하기

생성자나 setter에 List 를 파라미터로 두면 된다. public Class Xyz { private List<Daemon> daemons; @Autowired public void setDaemons(List<Daemon> daemons){ this.daemons = daemons; } }

2024-09-15 · 1 min · 24 words

TreeSet

지속적으로 정렬 상태를 유지하면서, 새로운 데이터가 추가/삭제가 자주 일어나는 경우가 있었다. 쉽게 말해서 균형 잡힌 이진 트리인 레드 블랙 트리를 사용해야 됐다. TreeSet은 Set 인터페이스의 구현체다. 대표 메서드 TreeSet에서 사용되는 대표적인 메서드를 정리해본다. E floor(E e): e 이하인 객체 중 가장 큰 값을 리턴한다. 없으면 null이 리턴된다. O(log n) E ceiling(E e): e 이상인 객체 중 가장 작은 값을 리턴한다. 없으면 null이 리턴된다. O(log n) E higher(E e): e 초과인 객체 중 가장 작은 값을 리턴한다....

2024-09-15 · 1 min · 126 words

transient란

Serializable 을 구현한 클래스에서 필드 중에 직렬화를 원치 않는 필드에 붙이면 된다. public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class); private static final HandlerAdapter HANDLER_ADAPTER = new DefaultHandlerAdapter(); private final transient HandlerMappings handlerMappings; public DispatcherServlet() { this.handlerMappings = new HandlerMappings(); } //... } https://nesoy.github.io/articles/2018-06/Java-transient

2024-09-15 · 1 min · 56 words