팀뷰어를 사용하다 보면 다음과 같은 오류로 팀뷰어를 사용하지 못할 때가 있다.

시간이 초과되었습니다.
시간 초과후 연결이 차단되었습니다. 현재 파트너로 연결하시려면 라이선스를 업그레이드 하시거나, 잠시후 다시 시도 하십시오.
이 파트너로의 연결이 10:00까지 차단됩니다. 

해당 문제를 검색한 결과, 무료 사용자에게는 연결 제한이 존재하는데 이를 초과할 경우 위와 같은 문제가 발생한다.

해당 문제는 LAN Driver의 주소를 변경하여 해결이 가능한데, 그 방법은 다음과 같다.

장치관리자 - 랜 카드 - 네트워크 주소(Locally Administered Address)

속성을 찾은 뒤, 해당 속성의 값이 없음(N) 이라면, 값을 000000000000 (12자리 수)를 입력하고 저장한 뒤에 윈도우를 다시 시작하면 된다.

값이 이미 설정되어 있다면, 해당 값을 변경하거나 없음(N)으로 설정하고 윈도우를 재시작 하면 된다.

변경 전
변경 후

만약 위와 같은 설정 후에도 팀뷰어에서 여전히 시간 초과 문제가 발생한다면, 다음과 같은 방법으로 문제를 해결할 수 있다.

1. 네트워크 설정을 원래 값으로 돌려놓는다
2. 윈도우를 재시작 한다.
3. 팀뷰어를 삭제한다.
4. 윈도우를 재시작 한다.
5. 네트워크 설정에서 값을 바꾼다.
6. 팀뷰어를 설치한다.

 

'기타' 카테고리의 다른 글

[GitHub] Link Github Respository  (0) 2021.01.16

이번에 갤럭시 버즈 프로가 생겼다. 기존에 버즈 1세대를 사용하고 있었는데, 음질 차이가 얼마나 클까 하는 생각이 있었고, 큰 기대는 하지 않았다. (애니콜 케이스만 너무 기대됐다.)

1월 30일에 삼성 갤캠스에서 주문 했는데, 2월 9일이 되어서야 배달을 받았다. (삼성 물류 노조 파업 때문에 꽤 오래 걸리는 것 같다.)

버즈 프로와 애니콜 박스

배송 받았을 때 버즈 프로보다 애니콜 케이스에 눈길이 더 갔고, 정말 너무 귀엽게 잘 만든 케이스인 것 같다.

버즈 프로 내부

그래도 버즈가 애니콜보다 더 귀한 몸이기 때문에, 버즈 프로의 박스를 먼저 열었고, 위 사진처럼 생겼다. 구성품은 버즈 프로 본체와 오른쪽 검정 박스에 USB Type C 선, 그리고 여분의 이어팁이 들어있다. 나는 귓구멍이 작기 때문에, 제일 먼저 버즈 프로의 이어팁을 S사이즈로 교체해주었다.

버즈 프로

이번 버즈 프로는 애니콜 케이스 뿐 아니라 색감도 정말 잘 뽑힌 것 같다. 원래 IT 기기는 떄 타면 안된다는 생각에 항상 검정색을 선호하는데, 이번에는 바이올렛이 예쁘게 나온 것 같아 바이올렛으로 선택했고, 후회할 일 없을 것 같다.

애니콜 케이스 장착

애니콜 케이스를 끼웠는데!! 너무 귀엽다!!! 이건 진짜 없는 사람은 따로 주문해서라도 끼워야 한다!!! 너무 귀엽잖아!!


버즈 1세대와의 비교

버즈 1세대와 비교는 "착용감", "음질", "배터리", "통화 음질", "기타 기능"으로 하겠다.

착용감

버즈 1세대 > 버즈 프로

사실 둘 다 귀에 끼우고 있을 때는 별 차이가 없다. 그런데 내가 큰 차이를 느낀 때는, 버즈를 귀에서 뺐을 때 귀의 어색함, 통증이 버즈 프로에서 꽤 크게 느껴졌다. 버즈 1세대에 적응해서 그런가? 버즈 프로를 귀에서 빼면 일단 귀가 "살것같아!"라고 하는 듯한 느낌이 든다. 이어팁을 사제로 구매해서 바꾸면 괜찮아진다는 말이 있기에, 구매 후 교체할 예정이다.

음질

버즈 1세대 << 버즈 프로

사실 별 기대하지 않은 음질이지만, 꽤 큰 차이가 느껴졌다. 버즈의 ANC를 끄고 들어도, 해상력이 꽤 좋아졌으며 버즈 1세대에서는 크게 들리지 않았던 여러 채널을 버즈 프로에선 들을수 있었다. 예를들어 드럼의 킥을 버즈에서는 '그냥 "킥"이구나'. 하고 느껴졌다면, 버즈 프로에서는 '오 "킥" 괜찮은데?' 하는 감이 느껴질 정도였으니.

배터리

버즈 1세대 > 버즈 프로 (19년부터 사용한 1세대의 수명 단축을 고려함)

프로에 더 많은 기능이 들어가서 그런가? 실제론 버즈 1세대의 사용 시간이 더 긴 것 같다. 사용했을 때는 둘의 차이를 크게 느끼지 못했지만, 수명이 줄어 든 버즈 1세대를 생각하면 프로가 더 짧은 것 같다.

통화 음질

버즈 1세대 <<~||넘사벽||~<< 버즈 프로

통화 음질은 말할 것 없다. 버즈 1세대는 통화할 때 무조건 버즈를 빼고 핸드폰으로 통화해야 했는데, 버즈 프로는 그냥 끼고 통화해도 사람들이 모른다. 심지어 여자친구는 핸드폰으로 통화하는 것 같다고 한다. 정말 정말 정말 정말 나는 이 통화 음질만으로도 정말 만족한다.

기타 기능

버즈 1세대 <<<< 버즈 프로

기타 기능은 ANC, 주변 소음 듣기, 대화 감지 등 버즈 프로에만 있는 기능들을 생각했을 때 당연히 버즈 프로의 압승이다. ANC는 정말 충격 받은게, 내 방에 컴퓨터 2대가 있는데 버즈 프로를 끼고 ANC 기능을 켜면 감쪽같이 컴퓨터의 팬 소리가 안들린다! 충격이었다. 처음에 ANC를 키고 꼈을때는 몰랐는데, ANC에서 주변 소음 듣기 모드를 처음 켰을 때 팬 소리를 듣고 헐! 대박인데? 하고 느껴졌다. 버즈 프로를 빼니, 컴퓨터의 팬 소리가 정말 크게 느껴지는게 아닌가!

주변 소음 듣기 또한 대박이다. 버즈 1세대의 주변 소음 듣기(비슷한 기능이 있는데, 이름이 기억 안난다. 똑같은가?)는 켜도 화이트 노이즈 그리고 떨어지는 기능으로 인해 별 의미 없는 기능이었는데, 버즈 프로의 그것은 정말 대박이다. 주변 사람과 자연스러운 대화가 가능하고, 그렇다 해서 버즈 프로가 재생하던 미디어가 안들리는 것도 아니다! 이것 정말 대박인데?

대화 감지 기능도 좋기는 한데, 항상 켜놓을만한 기능은 아닌 것 같다. 버즈 프로가 조금이라도 내가 말한다는 듯한 낌새를 파악하면 (작은 노래 흥얼거림이라던지, 기침이라던지, 기타 등등 마이크가 인식만 한다면) 곧바로 주변감지 기능이 켜지기 때문에, 미디어에 집중하긴 어렵기 때문이다. 그래서 나는 버즈 프로의 터치 기능을 ANC <-> 주변 소음 듣기 모드 변환으로 설정해 놓고, 대화 감지 기능은 꺼놨다.


다른걸 다 떠나서, 버즈 프로는 간만에 명작이 나온 것 같다. 

귀염뽀짝한 레트로 케이스들과 꽤 만족할만한 기능들, 그리고 재빠른 업데이트까지.

버즈 프로를 고민하고 있다면, 나는 꼭 추천하고 싶다.

이번엔 Queue와 관련된 자료구조에 대해 공부하려고 한다.

Queue는 Stack과는 반대로, FIFO(First In First Out)성질을 갖는다. 즉 먼저 들어온 녀석이 먼저 나간다.

Queue의 가장 흔한 예시로는 프린트 출력 대기열을 들 수 있는데, 먼저 출력 요청한 문서를 먼저 출력해야 하기 때문이다. 비슷한 예로 입장 대기줄 등이 있다. 

큐는 탐색에서도 스택과 함께 많이 쓰이므로 잘 알아두면 좋다. 특히 큐는 우선순위 큐, 원형 큐 ... 등 많은 종류가 있기 때문에, 기본 큐는 반드시 알아야 한다.


Queue에는 어떤게 필요할까?

Queue는 Stack과 비슷한 자료구조로, 데이터를 삽입하고 반환할 수 있어야 한다. Stack처럼 제일 위에 삽입한다고 생각해도 된다. 다만 Stack과의 차이점시작점과 끝점이 있어야 한다는 것이다. Stack은 top이라는 시작점만 존재했지만, Queue는 끝점도 가져야하는 이유는 다음과 같다.

1. 제일 먼저 들어온 녀석을 반환하기 위함
2. 큐가 가득 찼는지 확인하기 위함.

즉 Queue에도 Top만 존재했다면, 어느 녀석을 먼저 반환해야 할지, 새로 들어온 녀석은 어디로 들어와야 할지를 동시에 수행할 수 없기 때문에 끝점도 존재해야 하는 것이다.

그렇다면 rear는 어떻게 활용할 수 있을까? Queue에 데이터가 삽입되면 rear가 하나씩 증가하게 된다. 이를 조금 더 생각 해 보면, front와 rear가 같다면, Queue가 비어있는 상황이 되고, rear가 capacity와 같아지게 되면 Queue가 가득차게 되는 것이다.

따라서 Queue는 front, rear, capacity 그리고 queue를 담는 배열이 필요하다.


Queue 구현

Queue의 기본은 다음과 같다.

public class Queue {
	int front;
	int rear;
	int capacity;
	Object[] queue;
	Queue(int capacity){
		this.front = -1;
		this.rear = -1;
		this.capacity = capacity;
		queue = new Object[this.capacity];
	}
	
	public boolean isFull() {
    /*
    capacity가 10이면 배열은 0~9를 갖고, rear도 0부터 시작하기 때문에 -1을 해야한다.
    */
		return (this.rear == this.capacity-1); 
	}
	
	public boolean isEmpty() {
    /*
   	front와 rear가 같으면 비어있는 상태이기 때문에, 편의를 위해 front와 rear를 -1로 초기화 시켜준다.
    */
    	if(front == rear) {
			front = -1;
			rear = -1;
		}
		return (this.front == this.rear);
	}
}

다음으로 Queue에 데이터를 삽입하고 반환하는 함수가 필요한데, Stack에서는 이를 pop, push라고 했다면 Queue에서는 enqueue, dequeue라고 한다.

데이터를 반환하기 위해서는 front에 있는 먼저 들어온 녀석을 반환해줘야 하는데, 반환 해줄 때 마다 front의 위치를 옮겨주어야 한다.

 

왼쪽이 간편해 보인다.

위 그림을 보면, 다음 출력 문서의 위치 front는 고정되어 있고, 남아있는 문서들을 한칸씩 옮기는 오른쪽 그림과 다음 출력 문서의 위치 front를 이동시키고 남아있는 문서들은 고정되어 있는 왼쪽 그림중 어느 것이 더 편해 보이겠는가?

정답은 당연히 왼쪽 그림인 front를 옮기는게 훨씬 간단하다.

이렇게 dequeue에서 front를 옮기기 때문에, rear의 위치 또한 단순히 배열의 index를 옮겨서는 안되고, 한가지 트릭을 써야 한다. (만약 n칸짜리 queue에서 n개를 넣고 dequeue를 n번 하면, front와 rear의 크기는 같아지게 된다. 즉 queue는 비어있게 되는데, 문제는 rear의 위치가 capacity와 같아지기 때문에 동시에 가득찬 상황이 된다. 이는 Queue의 모순이지 않는가?)

rear에 사용할 트릭은, 단순히 index를 지정하는 게 아니라 Queue의 capacity로 나누어서 나온 몫이 rear의 index가 되게 해야 한다. 위 괄호안에서 든 예시로 말하자면, capacity가 10이라고 가정 했을 때, rear와 front는 모두 9가 되는 상황이다. 이 때, (rear+1) % (capacity = 10) 을 하면 삽입할 다음 index는 0이 되고, rear와 front의 차이는 다시금 10이 되기 때문에 처음부터 넣는것과 같게 된다. (+1을 해주는 이유는, 삽입할 element는 다음 번 index를 가져야 하기 때문이다.)

이를 바탕으로 enqueue를 설계하면 다음과 같다.

public class Queue {
	...
	public void enqueue(Object element) {
		if(isFull()) {
			System.out.println("Queue is Full!");
			return;
		}
		
		rear = (rear+1) % this.capacity;
		queue[rear] = element;
	}
    ...
}

dequeue 또한 enqueue와 같은 원리로 Queue의 capacity로 나눈 몫을 index로 가지면 된다. 이유는 위에서 rear에 대한 설명한 것과 같다.

public class Queue {
	...
	public Object dequeue() {
		if(isEmpty()) {
			System.out.println("Queue is empty");
			return null;
		}
		
		front = (front+1) % this.capacity;
		return queue[front];
	}
    ...
}

Queue도 Stack과 같이 element를 반환하지 않고 엿보는 peek을 가질 수 있는데, 코드는 다음과 같다.

public class Queue {
	...
	public Object peek() {
		if(isEmpty()) {
			System.out.println("Queue is empty");
			return null;
		}
		
		return queue[front+1];
	}
    ...
}

 

이제 queue의 size와 초기화를 시켜주는 함수를 만들면 된다.

size는 rear - front를 통해 구할 수 있다. 이는 내가 마지막으로 삽입한 index - 제일 먼저 삽입한 index가 되고, 5개 입력했으면 다음과 같기 때문이다 (5-0) = 5. 그런데 배열은 0부터 시작하기 때문에 front와 rear에 각각 1씩 더해주면 된다. ( (4+1) - (-1+1) ) = 5. 또한 Queue는 front와 rear의 index가 역전될 수 있으니, 절대값 으로 반환하면 된다.

초기화는 간단하게 front, rear, 모두 -1로, 그리고 queue 배열을 새로 선언하면 된다. 

코드는 다음과 같다.

public class Queue {
	...
	public int size() {
		return Math.abs( (rear+1) - (front+1) );
	}
	
	public void clear() {
		if(isEmpty()) {
			System.out.println("Queue is already empty!");
		}
		else {
			front = -1;
			rear = -1;
			queue = new Object[this.capacity];
			System.out.println("Queue has cleared!");
		}
	}
}

Queue 코드 전체 및 실행결과

 

public class Queue {
	int front;
	int rear;
	int capacity;
	Object[] queue;
	Queue(int capacity){
		this.front = -1;
		this.rear = -1;
		this.capacity = capacity;
		queue = new Object[this.capacity];
	}
	
	public boolean isFull() {
		return (this.rear == this.capacity-1);
	}
	
	public boolean isEmpty() {
		if(front == rear) {
			front = -1;
			rear = -1;
		}
		return (this.front == this.rear);
	}
	
	public void enqueue(Object element) {
		if(isFull()) {
			System.out.println("Queue is Full!");
			return;
		}
		
		rear = (rear+1) % this.capacity;
		queue[rear] = element;
	}
	
	public Object dequeue() {
		if(isEmpty()) {
			System.out.println("Queue is empty");
			return null;
		}
		
		front = (front+1) % this.capacity;
		return queue[front];
	}
	
	public Object peek() {
		if(isEmpty()) {
			System.out.println("Queue is empty");
			return null;
		}
		
		return queue[front+1];
	}
	
	public int size() {
		return Math.abs( (rear+1) - (front+1) );
	}
	
	public void clear() {
		if(isEmpty()) {
			System.out.println("Queue is already empty!");
		}
		else {
			front = -1;
			rear = -1;
			queue = new Object[this.capacity];
			System.out.println("Queue has cleared!");
		}
	}
}

아래는 실행코드이다.

public class mainQueue {
	public static void main(String[] args) {
		System.out.println("=====짧은머리 개발자=====");
		
		Queue queue = new Queue(10);
		
		queue.dequeue();
		
		for(int i = 0; i < 10; i++) {
			queue.enqueue(i);
		}
		
		System.out.println("isFull : " + queue.isFull());
		
		System.out.println("size : " + queue.size());
		
		for(int i = 0; i < 10; i++) {
			System.out.println("Dequeue : " + queue.dequeue());
			System.out.println("size : " + queue.size());
		}
		
		System.out.println("Dequeue : " + queue.dequeue());
		
		System.out.println("isEmpty : " + queue.isEmpty());
		
		queue.enqueue(555);
		System.out.println("isEmpty : " + queue.isEmpty());
		System.out.println("isFull : " + queue.isFull());
		System.out.println("peek: " + queue.peek());
	}
}

실행 결과

제네릭은 일부러 안했다. 여러분이 한번 해보세요! 쉬워요.

내가 만든 웹 서버가 HTTP가 아닌 HTTPS에서 통신하게 하려면 SSL이라는 인증서가 필요하다. Secure Socket Layer, 전송 계층 보안은 보안된 환경에서의 통신을 제공하기 위한 규약이다. 조금 왜곡을 보태 간단하게 말하면 HTTP의 취약한 해킹을 보안하기 위해 SSL을 이용함으로써 해킹으로부터 안전할 수 있는 것이다.

뿐만 아니라 간혹 웹서버 개발 중에 CORS 관련 오류나, 오류 내용에서 HTTPS에서만 가능하다. 는 문구를 확인할 수 있는데, 이를 해결하기 위해서는 HTTPS가 필요하다.

유료 HTTPS의 경우 비싼 돈이 들기 때문에 나같은 학생 개발자나 간단한 개발에서는 굳이 돈을 내고 쓸 필요가 없는데, 이 때 LetsEncrypt를 이용해 SSL 인증서를 무료로 발급받을 수 있다. (LetsEncrypt! 누르면 홈페이지로 이동)


LetsEncrypt를 우선 받아야 하는데, Github에 올라온걸 clone 해주면 된다.

git clone https://github.com/letsencrypt/letsencrypt [PATH/TO/DOWNLOAD] # 나같은 경우 /opt/letsencrypt

이후에 내려받은 폴더로 이용하여 certbot-auto를 실행시키면 된다.

certbot-auto certonly --manual --preferred-challenges=dns --email [이메일] --server https://acme-v02.api.letsencrypt.org/directory -d [SSL을 인증하고자 하는 도메인]

여러 도메인을 등록하고자 하는 경우 -d DOMAN1 -d DOMAN2 와 같이 -d를 이용해 추가해주면 된다.

이후에 certbot에서 시키는대로 하면 된다. 위 명령어가 동작하지 않는 사람들은 아래 명령을 이용하면 된다. 그러나 아래 방식의 경우 standalone이기 때문에, 위 명령어를 추천한다. 

cerbot-auto certonly --standalone -d [SSL을 인증하고자 하는 도메인]

 


사용 예시

$ ./certbot-auto certonly --manual --preferred-challenges=dns --email dev.whoan@gmail.com --server https://acme-v02.api.letsencrypt.org/directory -d *.dev-whoan.xyz

Requesting to rerun ./certbot-auto with root privileges...
Your system is not supported by certbot-auto anymore.
certbot-auto and its Certbot installation will no longer receive updates.
You will not receive any bug fixes including those fixing server compatibility or security problems.
Please visit https://certbot.eff.org/ to check for other alternatives. Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate Performing the following challenges:
dns-01 challenge for dev-whoan.xyz
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this certificate. If you're running certbot in manual mode on a machine that is not your server, please ensure you're okay with that.
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(Y)es/(N)o: Y

위에서 *.dev-whoan.xyz에 대한 와일드카드 SSL 인증서 발급을 요청했고, 이후에 설명이 나온다. IP 로그에 대해 거절(N)하면, SSL 발급이 취소된다. Y를 입력하면 다음과 같이 DNS TXT 레코드를 입력하라고 하는데(도메인 주인 확인을 위한), 사용중인 도메인의 TXT 레코드를 추가해주면 된다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.dev-whoan.xyz with the following value:
입력해야할 TXT 값
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

이 때, TXT 레코드를 추가해 줄 때 _acme-challenge만 TXT name으로 입력해주면 된다. 뒤의 dev-whoan.xyz까지 모두 입력하면 안된다. (모두 입력하면 txt는 _acme-challenge.dev-whoan.xyz.dev-whoan.xyz에 기록되기 때문)

이후에 다음과 같은 글이 뜨면 성공!

Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: dev.whoan@gmail.com).
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/dev-whoan.xyz/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/dev-whoan.xyz/privkey.pem
Your cert will expire on 2021-05-04. To obtain a new or tweaked version of this certificate in the future, simply run certbot-auto again. To non-interactively renew *all* of your certificates, run "certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

이 외의 글이 뜨면 오류도 함께 출력되니, 그에 맞게 해결하면 된다. (대게 와일드 카드 혹은 TXT 레코드를 이용한 도메인 주소 검증에서 실패하는 경우, _acme-challenge를 잘못 설정해서 그런 경우다.)

하루에 10번 이상인가? 실패하면 24시간 이후에 인증서 발급이 가능하니 주의하도록 하자.

* 참고로 와일드 카드의 경우 자동 갱신이 불가능하기 때문에, 주의하길 바란다.

와디즈를 자주 보는 편인데, Type C 레드빈 마그네틱 코어7 최대 100w 충전 선이 있길래 펀딩했다. 친구초대 이벤트로 15000P가 있었는데, 이를 사용하여 거의 공짜에 가까운 가격으로 펀딩했다.

스마트 기기가 늘어감에 따라 동시에 충전할 수 없을까 하는 생각이 있었고, 때마침 최대 120W Type C *2, 65W Type A * 2 짜리 충전기를 펀딩 해놓은 상태라, 그에 걸맞는 속도를 내는 USB 선도 필요하여 펀딩했다.

Type C 플랫형으로 스마트폰용 하나, 태블릿용 하나 총 2개를 구매했고, 드디어 펀딩한 제품을 배송받았다.

충전 선과 마그네틱 코어7 커넥터


알고보니 제품이 잘못 배송되어 다시 받았다.

아직 따로 펀딩한 타사의 충전 어댑터는 배송을 받지 못해서 제 속도를 테스트해보진 못하지만, (속도는 노트북에 연결하여 얼마나 빠른 시간에 충전되는지를 통해 확인할 예정이다). 일단 갖다 대기만 하면 착 붙는 마그네틱 속성 덕분에 꽤 편리하게 단말기 충전을 하고 있다.

갖다 대면 붙는다

사실 갖고 있는 플립은 최대 15W라서 (...) 별 의미 없지만, 위 영상처럼 그냥 근처에 두면 붙기 때문에 편의성에 의의를 두기로 했다. (...)

최대 45W 보조배터리를 통해 탭7을 충전해보니까 꽤 빠르게 충전된다. (그래봤자 이전 25W에 비해 10분정도밖에 안빨라졌지만.. 이건 삼성 충전 속도 때문이니..)

여튼 선이 착 붙는 편의성과 편리성은 정말 최고다!

오래전부터 태블릿에서 사용할 무선 마우스가 있으면 좋겠다는 생각을 했다. 그래서 태블릿에 사용할 무선 마우스를 찾고 있었는데, 내게 필요한 조건은 다음과 같았다.

1. 태블릿과 블루투스 페어링을 통해 연결이 되어야 할 것
2. 태블릿 이외의 다른 기기에도 연결이 가능해야 할 것
3. 오랜시간 사용해도 손에 무리가 적을 것
4. 적당한 가성비가 있어야 할 것

1번과 2번을 충족하는 제품은 많이 있었지만, 이와 동시에 3, 4번을 충족하는 제품은 없었다.

대표적으로 로지텍의 Anywhere, M720, 그리고 페블을 눈에 두고 있었지만 Anywhere은 너무 비쌌고, 로지텍 페블은 시기만 맞으면 1만원 중후반대에 제품을 구매할 수 있었지만 생김새 때문에 3번을 충족하지 못했다.

그래서 Anywhere와 페블의 중간에 형성중인 가격대, 3번을 충족하는 로지텍의 M720을 구매할 까 많이 생각했지만 4만원이라는 돈을 주고 사기에는 너무 아까웠다.

마우스 사는것을 위와 같은 이유로 미루고 미루다 어느날 페이스북의 광고에 내가 마우스 검색한 것을 인지했는지, 샤오미의 무선 마우스 광고가 나오는게 아닌가?

샤오미 하면 가성비, 그리고 이미지로 봤을 때 딱 느껴지는 오래 사용해도 손목에 무리가 적을 것 같은 생김새!

그래서 바로 구매를 했다. 12900원의 제품 가격과 배송비 2500원을 합해 15400원에 구매했으니, 페블보다도 저렴한 것이 아닌가!!


배송받은 제품은 다음과 같이 생겼다.

박스 전후면

제품을 구매할 때는 무소음 마우스인지 몰랐는데, 박스 전면에 Silent Edition이라 적혀있는 걸 보고 무소음 마우스라는걸 알았다.

후면에는 각종 설명이 중국어로 적혀있기 때문에, 눈길을 주지도 않았다.

개봉 하면 다음과 같이 생겼는데, 구성품은 정말 마우스 본체 하나, 제품 취급 설명서, 그리고 제품 사용 설명서 이렇게 3개가 들어있다. 건전지는 동봉되어 있지 않으니 따로 AAA 건전지 두 개를 준비해야 한다.

구성품

마우스의 전원을 위해 AAA 건전지 2개가 필요한데, 나는 여타 제품과 같이 AA 한개일 줄 알고 AA를 준비했는데,, 이로인해 AAA 건전지를 따로 구해야 했다. ㅠㅠ..

건전지 넣는법

건전지를 넣기 위해서는 마우스 바닥면에 있는 뚜껑(?)을 열어야 되는데, 위 사진처럼 시침 처럼 생긴 것을 왼쪽 파란 선까지 돌리면 열린다.

이후에 건전지를 넣어주면 된다. 건전지 사이에 보이는 동글이가 리시버다. 사용하고자 하는 데스크탑이나 노트북 등 USB를 꽂으면 연결된다.

본 제품은 기본적으로 블루투스 1대, USB 1대 총 2대의 연결만 지원하기에 비교대상이었던 로지텍의 타 제품은 3대 이상인걸 생각하면 아쉽긴 하지만, 12900원의 제품에서 그것 까지 바라는건 양심이 없는 것 같긴 하다.ㅋㅋㅋ


제품의 상단을 보면 마우스 휠 아래에 동그란 버튼이 있는데, 이 버튼이 바로 USB로 연결 할지, 블루투스로 연결할지 결정하는 버튼이다.

초록색은 USB 리시버, 파란색은 블루투스와 연결중이라는 의미다.

초록 불은 USB 리시버와 연결, 파란불은 무선 블루투스 연결을 의미한다.
Mi Silent Mouse를 찾아 연결하면 된다.

블루투스로 연결하려 했는데, 만약 제품이 안뜬다면 마우스에 있는 동그란 버튼을 꾹 누르면 깜빡깜빡 거리며 페어링 모드로 진입하게 되고, 이 때 블루투스 검색란에서 Mi Silent Mouse를 찾을 수 있다. (새로운 기기에서 블루투스 페어링을 할 때도 이렇게 하면 된다.)

 

진짜 무소음이다!

마우스 버튼을 눌러보면 왼쪽 클릭과 오른쪽 클릭 버튼은 정말 무소음에 가까운 걸 알 수 있다. 다만 좌측에 존재하는 페이지 앞/뒤 버튼은 무소음이 아니니, 독서실 등 조용한 곳에서 사용할 떄 주의해야 할 것 같다.


총평 (★☆ - 4.5개임 사실)

12900원 짜리 마우스가 이렇게 높은 퀄리티를 보여줄 줄이야! 생김새도 무난하고, 사용성도 무난하고!

다만 별 한개를 깎은 이유는 데스크탑에서 DPI 설정이 안된다. 너무 빠르다. (사실 별점 4.5개를 주고싶은데 반쪽 짜리 별은 없어서..)

그걸 제외하면 정말 이건 정말 좋은 제품이다. 

내 태블릿에 K380과 더불어 오래 쓸 녀석이다.

두 달정도 전 쯤에 키보드에 콜라를 쏟았던 적이 있다. 우측 Ctrl 키 부근에 쏟았는데, 작동도 잘 되고 딱히 불편함이 없어서 A/S를 보내지 않고 계속 쓰고 있었다.

음료를 쏟은지 한 달이 지나자 Ctrl 키를 눌러도 올라오지 않는 증상이 생겼다.

눌러도 올라오지 않는 Ctrl 키..

레오폴드 키는 특히 '한자' 키가 우측 Ctrl키와 함께 동작하는데, 내가 '한자'를 얼마나 자주 쓰는지 이 경험을 통해 알게 됐다.

불편함을 느끼게 되자 매우 신경쓰이고, 도저히 못쓰겠다 싶어서 레오폴드 공식 홈페이지에서 A/S를 신청하였고, 택배를 보낸지 2주쯤 지나자 수리된 제품을 받아볼 수 있게 됐다. (레오폴드는 우체국을 통해 택배를 보내니, A/S를 맡기고 연락이 없다면 우체국 앱을 통해 조회해 보자.)

레오폴드 A/S는 추가금이 발생할 때만 연락 온다고 알려져있는데, 이번주 월요일 레오폴드로부터 연락을 받아 속으로 많이 놀랐었다. (콜라 특성에 의해 기판이 부식되어 추가금이 발생하는건가..?ㅠㅠ)

전화를 받아보니, 내가 증상으로 첨부한 동영상의 기간이 만료되어 증상 확인이 불가능해 확인차 연락주신것 이었다.


A/S 언박싱!

레오폴드의 A/S는 키보드의 삼성급이라 알려져 있던 만큼 꽤 기대하고 있었다. (다른 분들의 후기를 보면 보낸지 3일만에 받은 사람도 있어서 시간적으로도 금방 될거라 기대했지만..ㅠㅠ 2주가 걸렸다. 기간은 레오폴드 공식 홈페이지에 매번 공지되니 잘 확인하면 좋을것 같다.)

뽁뽁이는 가지런하게 잘 싸여 왔고, 뽁뽁이를 뜯은 박스의 상태가 꽤 깨끗해서 새 박스인가? 하는 착각이 들 정도였다.

박스를 열면 키보드 위에 뽁뽁이를 올려주신 후기도 봐서 나도 그러면 좋겠다는 생각을 했지만, 나는 그냥 키보드만 왔다. ㅠㅠ (그런데 박스 내부가 보낼 때 닦아서 보냈는데 먼지가 많이 쌓여서 왔다. 2주간의 기다림 때문인가..?)


 

키보드는 정상적으로 동작하는 것을 모두 확인했다. 무엇보다 전보다 키들이 더 부드러워 진 것 같은 착각도 든다.

키보드 수리기간 동안 블루투스 키보드를 사용하면서 손목이 꽤 많이 아팠는데, 이제 안아파도 된다는 생각에 너무 좋다.

이상으로 레오폴드 A/S 후기를 마치겠다.

중앙화 블록체인을 만들면서 Transaction을 효율적으로 검색할 수 있는 시스템을 개발하던 중, ElasticSearch라는 기술을 알게됐다.
기존에는 파일 형태로 Transaction을 저장하려 했으나, 이후 주어진 Transaction을 검증하는데 있어 오랜 시간이 소모될 것 같아 해결법을 강구하던 중 알게된 기술이다.
ElasticSearch는 기본적으로 REST API 통신으로 데이터를 조작할 수 있었고, 여기에 Transaction 저장방식을 객체형 DB인 MongoDB에 저장하기로 했다.

File로 저장할 때에도 JSON 타입으로 저장하여 ElasticSearch를 연계할 수 있었지만, 그냥 파일로 저장 안하고 MongoDB에 저장하기로 결정했다. (MongoDB에만 Transaction을 저장하는건 문제가 될 수 있지만, 개발하고 있는 블록체인에서는 Authenticator라는 역할이 몇명 존재하기 때문에, 여기에 약간의 분산저장을 하고 있어서 크게 신경쓰지 않기로 했다.)

Linux와 관련된 글은 많았으나, 이번에 개발하는 서버가 Windows 기반이기에 관련 자료가 거의 없다싶이 하여 글을 쓰게 됐다.

구현하고자 하는 기능은 다음과 같다.
MongoDB에 어떤 데이터가 저장되면 ElasticSearch의 데이터로 동기화시켜 데이터를 구할때는 MongoDB가 아닌 Elastic Search에서 가져올 것이다.


사용된 MongoDB와 ElasticSearch 그리고 Logstash의 버전은 다음과 같다.

MongoDB: 4.3.3 - https://www.mongodb.com/
ElasticSearch: 7.10.1 - https://www.elastic.co/kr/downloads/elasticsearch
Logstash: 7.10.2 - https://www.elastic.co/kr/downloads/logstash

Logstash를 설치한 이후에, mongodb input 플러그인을 설치해줘야 하는데, 정말 쉽게 cmd로 설치할 수 있었다. (관련된 글들이 모두 linux 기반이고, 명령어 또한 linux의 그것과 닮았기에 윈도우에서 동작 안할 줄 알았는데, 된다. 이걸로 이틀은 날려먹은 것 같다.)

cmd 명령 프롬프트 창을 관리자 권한으로 실행시킨 뒤, 다음 명령어를 입력하면 logstash-input-mongodb가 설치된다.

cd \path\to\logstash\bin\logstash-plugin install logstash-input-mongodb

만약 Success to installation( 정확히 기억 나지는 않지만 )과 같이 설치에 성공했다는 문구가 안뜨면, 오류가 함께 출력되니 그에 맞춰서 대응하면 된다.

이후 logstash를 이용하여 mongodb로부터 데이터를 가져와 elasticsearch로 넘겨주는 설정이 필요하다.
해당 설정은 다음과 같다.

# Sample Logstash configuration for receiving # UDP syslog messages over port 514 input { mongodb { uri => '몽고DB 주소' placeholder_db_dir => '입력 저장할 파일 경로' placeholder_db_name => '저장할 파일 이름' collection => '가져올 collection 이르' batch_size => 2000 generateId => false parse_method => "simple" } } filter { mutate { copy => { "_id" => "[@metadata][_id]"} remove_field => ["_id"] } } output { elasticsearch { hosts => ["엘라스틱 서치 주소"] index => "데이터를 삽입할 index 명" document_id => "%{[@metadata][_id]}" } stdout { } }

batch_size: 한번에 가져올 수 있는 최대 양 이다.
placeholder_db_dir에 저장된 placeholder_db_name을 지운다고 해서 Elastic Search에 동기화된 내용이 삭제되는 것은 아니다. 따라서 데이터의 삭제를 위해서는 elastic search에서 직접 제거해주어야 한다.

filter같은 경우에 엘라스틱 서치의 _id와 몽고db의 _id가 겹쳐서 오류가 발생할 수 있기 때문에, 몽고db의 _id를 나는 제거해주었다.

파일 명은 mongodb.conf 이며, 저장 위치는 logstash가 설치된 폴더의 config 폴더 내에 저장했다. ( \logstash\config\mongodb.conf\ )

이후 logstash를 실행 시켰을 때 정상적으로 실행된다면 성공이다.

사실 몽고DB와 엘라스틱 서치는 따로 건드리는 것 없이 logstash만 잘 설정해주면 작동해야만 한다.
몽고DB와 엘라스틱 서치가 정상적으로 동작하지만, sync가 안된다면 logstash의 설정에서 무엇인가 잘못된 것이니 logstash에서 찍히는 log를 잘 읽어보면 해결할 수 있을것이다.

+ Recent posts