일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 유레카
- 메모이제이션
- 이분 매칭
- ZuulFilter
- 스택
- 도커
- Spring Cloud Config
- 게이트웨이
- 트리
- docker-compose
- 서비스 디스커버리
- Gradle
- 백트래킹
- spring cloud
- Zuul
- 달팽이
- 주울
- Logback
- 플로이드 와샬
- 다익스트라
- spring boot
- 구간 트리
- 이분 탐색
- BFS
- dp
- 스프링 시큐리티
- 비트마스킹
- 구현
- Java
- 완전 탐색
- Today
- Total
목록분류 전체보기 (387)
Hello, Freakin world!
EventContainer - 이벤트 최상위 계층의 컨테이너 클래스다. 필드 객체에 필요한 객체를 주입한는 역할을 한다. EventLoop - 이벤트를 받아서 계속 처리하기 위한 클래스다. EventHandler - 이벤트에 대한 핸들러를 위한 클래스다. SelectManager - selector 객체의 생성과 파괴의 책임을 담당하는 클래스. selector 객체를 무조건 이 클래스를 통해 제공받는다.
아직 채팅방같은 클라이언트들끼리의 선별적인 대화는 x 서버가 최대 수용할 수 있는 클라이언트 수는 2명이라고 가정한다. 클라이언트는 상대 클라이언트가 접속했을 경우와 나갔을 경우 메세지를 통해 알 수 있다. 채팅 메세지등 모든 네트워크 요청은 서버를 통해 이루어진다. 자, 이제 두 명의 사용자가 대화가 가능하도록 해보자!!
다시 ClientChannelManager 클래스로 돌아와서 작성했던 기능들의 단위테스트를 작성해보자. 아래는 ClientChannelManager 클래스의 코드다. import ... /* 이 클래스의 책임은 어디까지인가? 단순하게 채널 객체의 생성과 반환만을 책임진다. */ public class ClientChannelManager { private SocketChannel socketChannel; private Logger logger = Logger.getLogger(ClientChannelManager.class.getCanonicalName()); private SocketAddress serverAddress; public ClientChannelManager(){} public sync..
BDD 방식의 테스트도 의미가 없다. IO 메서드의 기능을 제대로 테스트하기 위해서는 어찌됐든 서버가 필요하다. 선택지는 두 가지다. 1. Mock 서버를 작성하고 다른 스레드에서 실행시킨다. 2. 실제 서버를 켜놓고 테스트를 진행. 1번도 번거롭고, 2번도 구리다. 1번이 번거로운 이유는 클라이언트의 기능 테스트가 점점 늘어날 수록 Mock서버도 커지게 된다는 점때문이다. 비동기 메서드와 테스트 메서드 간에 어떤 예외가 던져질지도 미지수다. 2번은 더 치명적이다. 수동으로 계속 서버를 켜줘야하며, 자동화된 테스트가 불가능하다. 결론 : 1번으로 진행하자... 내가 테스트의 비중을 너무 간과하고 간단하게만 해결하려고 한건지도 모른다. 테스트에 품을 더 들이자.
이 부분은 꽤 골치아픈 부분이었다. 우선 아래 사진을 한번 보자. 이벤트 루프 스레드를 만든 이유는 위의 그림처럼 selecter(셀렉터의 객체)의 select() 메서드를 반복 수행하기 위함이다. (참고 : select() 의 역할은 실행할 수 있는 이벤트가 최소한 하나가 있을 때까지 대기하는 일종의 blockingQueue와 비슷함.) 가장 고민됐던 부분은 selector 객체를 어디서 관리하느냐는 문제였다. 고민하기에 앞서, selector 객체는 전역적으로 사용되기 때문에 반드시 공개되어져야 한다. 두 가지 선택지가 있다. 1. 이벤트 루프 스레드 내부에서 생성하고 스레드를 시작하기 전에 selector 객체를 초기화해 외부에 공개한다. 2. 외부에서 selector 객체를 관리하고 이벤트 루프 ..
Java NIO 에서 지원하는 셀렉터를 이용하면 하나의 serverSocketChannel로 다중의 클라이언트 채널에 대응할 수 있다. 그리고 위 그림은 클라이언트의 연결 요청에 대한 처리만을 그림으로 나타낸 것이다. (채널은 기본적으로 양방향 통신이 가능한데, 나중에 차차 추가하도록 하자.) 셀렉터에는 각 채널의 register 메서드를 통해 selector에 등록할 수 있는데, 이벤트 주도 모델에서 이벤트를 등록하는 개념과 유사하다. 위 그림에서 셀렉터는 eventLoop를 처리하는 다른 스레드에서 작동한다. 만약 서버가 클라이언트에 대해서 이벤트를 던지기만 한다면 굳이 또 하나의 스레드를 추가해서 구현할 필요가 없다. 하지만 이벤트의 발원지가 서버가 아닌 클라이언트인 경우, 이 이벤트를 감지하기 위..
클라이언트 부분부터 작성해보자. 클라이언트는 main 메서드를 이용해 시작된다. 다음과 같은 코드가 있다. import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class Main { static Logger logger = Logger.getLogger(Main.class.getCanonicalName()); public static void main(String[] args) throws IOException { System.out.println("채팅앱 시작"); System.out.println("서버와 연결 시도 중."); /* 서버와 연결 코드 */ System.out...
오늘 할 일 - 채팅앱 코드 한줄 - 블로그 글 작성 1개 - 일기 쓰기 - 독서 1줄 할 거(우선 순위 순) - 자바 비동기 프로그래밍, 네트워크 관련 토이프로젝트(채팅 기능 구현하기?) - vue.js 이용해서 간단한 게시판 만들기(뒤집어 엎고 다시 시작) - JPA 학습 - 최종 프로젝트 안드로이드 쇼핑몰 앱 만들기?
ViewModel 왜 쓰는거지? ViewModel을 쓰는 가장 큰 이유는 코드를 액티비티, 프래그먼트 생명주기에 종속되지 않게 할 수 있다는 점 때문이다. 위 그림처럼 ViewModel의 생명주기는 액티비티 생명주기와 독립적이다. 보통 onCreate에서 viewModel 객체를 생성한다. 이럴 경우 액티비티가 finish될 때까지 viewModel 객체는 유지된다. 따라서 앱의 설정 변화와 무관하게 데이터를 유지하고 가져올 수 있다. 뷰모델의 위와 같은 특징 때문에 데이터 로직을 UI와 분리시켜 작성할 수 있다. 그리고 LiveData 와 함께 사용하면 좀 더 리액티브한 프로그래밍을 할 수 있다. LiveData는 또 뭔데? 이 클래스는 변화가 감지 가능한 데이터 홀더 클래스다. 음... 어렵게 생각할..