지난 주에 저는 웹캠프 자그레브는 개발자와 디자이너를 위한 훌륭한 컨퍼런스입니다. 저는 '디바이스가 서로 대화하게 하세요'라는 제목으로 프레젠테이션을 했습니다. 데모 부분에서는 같은 네트워크에서 실행 중인 다른 사람과 자동으로 동기화되는 아주 간단한 메시지 앱을 만들었습니다. 슬라이드 및 데모 코드가 켜져 있습니다. github. 프레젠테이션은 촬영이 완료되었으며 곧 온라인에 공개될 예정입니다.
이번 발표의 주제는 IoT(사물 인터넷), M2M(머신 투 머신) 그리고 탈중앙화. 인터넷의 이러한 모든 것들은 일반적으로 데이터(대부분의 경우 매우 사적인 데이터, 예, 정량화된 자기 움직임)를 클라우드 어딘가에 있는 서버로 전송합니다. 이는 기본적으로 더 이상 사용자의 (개인) 데이터가 아니라는 것을 의미합니다. 이것은 매우 슬픈 일입니다. 이것이 제가 이 강연을 하게 된 주된 이유입니다. 하지만 디바이스가 서로 대화해야 하는 다른 좋은 이유도 많이 있습니다. 그리고 이것은 새로운 것이 아닙니다. 현재 우리가 M2M이라고 부르는 것은 수년 동안 업계에서 매우 일반적이었습니다.
하지만 다시 원래 주제로 돌아가 보겠습니다. 이러한 중앙 집중화를 피하는 한 가지 방법은 인터넷의 사물이 인터넷의 사물이 아닌 홈 네트워크의 사물이 되는 것입니다. 이들은 서로 통신을 시작하고, 라즈베리파이 또는 JVM을 지원하는 다른 소형 장치에서 실행되는 Couchbase Lite 인스턴스처럼 사용자가 결정한 곳에서 데이터를 전송해야 합니다.
물론 기기가 서로 대화할 수 있도록 하는 한 가지 방법은 이들 기기에 Couchbase Lite를 설치하고 P2P 동기화를 사용하는 것입니다. 이미 여러 블로그 게시물 이 문제가 있습니다. 그래서 이 문제를 해결하기 위해 자동 동기화를 설정하는 방법을 알려드리겠습니다.
동기화는 복제 링크를 기반으로 합니다. 일반적으로 주소와 자격 증명이 필요합니다. 저는 최대한 마찰을 줄이고 싶어서 자격 증명/보안 부분을 생략했습니다. 그 덕분에 프레젠테이션 데모를 훨씬 쉽게 만들 수 있었습니다. 그렇다면 주소만 있으면 어떻게 자동으로 주소를 받을 수 있을까요?
P2P 동기화가 작동하려면 동기화되는 디바이스가 동일한 네트워크에 있어야 합니다. 다행히도 자동 서비스 검색을 위한 여러 네트워크 프로토콜이 존재합니다. 봉쥬르, 랑데부, 제로컨프, 안드로이드 NSD, mDNS, DLNA, UPnP 등을 들어보셨을 겁니다. 대부분은 DNS 서비스 레지스트리를 기반으로 합니다. DNS는 IP를 호스트에 매핑하는 것 이상의 역할을 할 수 있기 때문입니다. 주소, 이름, 설명이 포함된 서비스 목록도 저장할 수 있습니다.
이것이 제가 데모에서 사용한 것입니다. 저는 간단한 Java 구현을 선택했습니다. JmDNS 라이브러리. 이렇게 하면 Java 네이티브 앱과 Android에서 거의 동일한 임팩트를 사용할 수 있습니다. UDP 브로드캐스팅을 통해 작동합니다. 네트워크에 연결된 다른 사물에 패킷을 보냅니다.
다음은 가장 관련성이 높은 코드를 간략하게 살펴보는 내용입니다.
장치에서 카우치베이스 라이트 리스너를 시작하여 연결을 수신할 수 있도록 합니다.
1 2 3 4 5 6 7 8 9 |
public int startCBLiteListener(int 포트) { 라이트 리스너 ls = new 라이트 리스너(데이터베이스.getManager(), 포트, null); 스레드 스레드 = new 스레드(ls); 스레드.시작(); 반환 ls.getListenPort(); } |
JmDNS를 사용하여 새 서비스 노출하기
1 2 3 4 5 6 |
public void 노출 서비스(int 포트) 던지기 IOException { 서비스 정보 sInfos = 서비스 정보.create(SERVICE_TYPE, 서비스 이름, 포트, 서비스_설명); jmdns.등록 서비스(sInfos); } |
JmDNS를 사용하여 특정 서비스 듣기. DiscoveryListener 리스너는 실제로 동기화를 설정할 수 있는 곳이기 때문에 중요합니다.
1 2 3 4 5 |
public void listenForService(){ jmdns.추가 서비스 리스너(SERVICE_TYPE, new DiscoveryListener(데이터베이스, jmdns, 서비스 이름)); } |
가장 깔끔한 구현은 아니지만 아이디어를 얻을 수 있을 것입니다. serviceResolved 메서드를 자세히 살펴보세요. 네트워크에서 새 서비스가 발견되었을 때 호출되는 메서드입니다. 이 메서드는 서비스의 URL을 제공하므로 클래식 복제 링크를 구성할 수 있습니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
패키지 org.카우치베이스.devex; 가져오기 com.카우치베이스.lite.데이터베이스; 가져오기 com.카우치베이스.lite.리스너.라이트 리스너; 가져오기 com.카우치베이스.lite.리플리케이터.복제; 가져오기 javax.jmdns.JmDNS; 가져오기 javax.jmdns.서비스 이벤트; 가져오기 javax.jmdns.서비스 리스너; 가져오기 자바.io.IOException; 가져오기 자바.net.URL; /** * 작성자: ldoguin 13/02/15에 작성했습니다. */ public 클래스 DiscoveryListener 구현 서비스 리스너 { 비공개 데이터베이스 데이터베이스; 비공개 JmDNS jmdns; 비공개 문자열 서비스 이름; public DiscoveryListener(데이터베이스 데이터베이스, JmDNS jmdns, 문자열 서비스 이름) { 이.데이터베이스 = 데이터베이스; 이.jmdns = jmdns; 이.서비스 이름 = 서비스 이름; } @오버라이드 public void 서비스 추가(서비스 이벤트 이벤트) { 만약 (! 서비스 이름.같음(이벤트.getName())){ jmdns.요청 서비스 정보(이벤트.getType(), 이벤트.getName(), 10); } } @오버라이드 public void 서비스삭제됨(서비스 이벤트 이벤트) { 시스템.out.println(이벤트.getName() + " 제거됨"); } @오버라이드 public void 서비스 해결(서비스 이벤트 이벤트) { 시스템.out.println("해결됨"); 문자열[] 서비스 URL = 이벤트.getInfo().getURLs(); 에 대한 (문자열 URL : 서비스 URL) { 시스템.out.println(URL); 설정 동기화(데이터베이스, URL + "/메시지"); } } public void 설정 동기화(데이터베이스 데이터베이스, 문자열 syncUrl) { 시도 { URL URL = new URL(syncUrl); 복제 pullReplication = 데이터베이스.createPullReplication(URL); pullReplication.setContinuous(true); pullReplication.시작(); 복제 pushReplication = 데이터베이스.createPushReplication(URL); pushReplication.setContinuous(true); pushReplication.시작(); } catch (IOException e){ throw new 런타임 예외(e); } } } |
그리고 이는 모든 Couchbase Lite 장치가 쉽게 동기화될 수 있도록 구현하기 쉬운 재미있는 실험 프로젝트입니다. 물론 할 수 있는 일은 훨씬 더 많습니다. 예를 들어 보안 부분을 추가하는 것이죠. 자격 증명을 한 번만 교환하는 첫 번째 수동 동기화를 수행한 다음 다른 모든 작업을 자동으로 수행하는 것을 상상할 수 있습니다. 도움이 되셨기를 바랍니다. 주저하지 마시고 의견을 남겨 주세요!