본문 바로가기

프로그래밍

Native Message (Chrome)

출처 : http://aimez.egloos.com/1869185

Nativemessage란

NPAPI를 대체할 것을 찾던 중.PPAPI를 품은 NaCl에 희망을 걸어 보았지만 외부dll을 dynamic linking하기 어렵다는 것을 알게되어 다른 대체할 것을 찾던중. Native Message라는 것을 발견함.

네이티브 메시지를 이용하면 크롬 Extension(app)에서 외부프로그램(host)과 json형태로 메시지를 주고받을 수있다.(std input & output 이용)

 

이를 이용하여 간단한 dll연동까지 가능한 것을 확인하였고 페이지에 영상에 대한 부분을 제대로지원한다고나와있지는 않았기 때문에 몇 가지 실험이 필요함에 따라 1024 x 768 영상을 base64로 인코딩 해서(C#으로 간단히) Extension으로 초당 100회정도 보내는 간단한 예제를 진행해봄.


Nativemessage 작동원리 구조

네이티브 메시지를 위해서는 host쪽에도 manifest를 등록해줘야 함.

Ex) {

           "name":"com.my_company.my_application",

           "description":"My Application",

"path":"C:\\Program Files\\MyApplication\\chrome_native_messaging_host.exe",

           "type":"stdio",

           "allowed_origins":[

              "chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"

]

}

 host manifest 파일은 유효한 JSON파일이어야 함.

아래 표와 같은 규칙을 지켜 작성할 것

Name

Description

Name

네이티브 메시징 호스트의 이름

클라이언트들이 runtime.connectNative또는 runtime.sendNativeMessage에 의해 이 메시지를 전달한다.

Name 부분에는 소문자와 ‘_’, ‘.’만 포함될 수 있다.

‘.’으로 시작하거나 끝날 수 없고, ‘.’바로 뒤에 ‘.’이 올 수 없다.

description

어플리케이션에 대한 간단한 설명

Path

네이티브 메시지 호스트 바이너리의 경로

리눅스나 OSX에서는 무조건 절대경로 사용

Windows에서는 manifest 파일이 위치한 부분부터 상대경로 가능.

Type

네이티브 메시지 호스트와 통신할 때 사용하는 인터페이스 타입으로 현재는 stdio만 지원.

크롬이 stdin, stdout을 이용해 호스트와 통신한다는 것을 나타내기 위함.

Allowed_origins

네이티브 메시지 호스트에 접근할 수 있는 Extension list

*.* 같은 regular expression 사용 불가

 

manifest파일의 위치는 플랫폼에 종속적.

Windows에서는 manifest파일이어디에든 있을 수 있다.

Application installer(예제파일의 install.bat)은 무조건 레지스트리키를 생성한다.

HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application

또는HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application

에 등록하고

manifest파일로 가는 총 경로를 기본 값으로 설정한다.

Ex) REGADD"HKCU\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application"/ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /f

 

다른 방법도 있다고 하나 확인해보지 못함.

추가로 chrome에서 nativemessage host를 검색할 경우 32-bit registry를 조회 후 64-bit registry를 조회함.


Nativemessaging protocol

크롬은 각각의 native messaging host를 각각 분리된process로 시작하고 standard I/O로 소통한다.

메시지는 JSON, UTF-8로 인코딩되어 직렬화되고 메시지의 길이를메시지의 앞부분에 32bit만큼 할당하여 표시함.

 

Native application이 오작동하는 것을 방지하기 위해 native messaging host에서 보낼 수 있는 단일 메시지의 최대 길이는 1MB로 설정되어 있음.

추가로 native messaging host로 전송되는 최대 메시지의크기는 4GB.

 

메시지 포트가 runtime.connectNative를 사용하여 생성되었을때크롬은 native messaging host를 시작하고포트가 사라질 때까지 process를 구동.

runtime.sendNativeMessaging를 이용하여 메시지포트를 생성하지 않고 메시지를 전송할 경우 크롬은 각각 메시지에 대해 새로운 native messaginghost를 생성.

 

추가로 host process에서 첫 메시지가 만들어 지면 이 호스트프로세스는 원래의 request에 대한 response로처리된다즉 크롬은 runtime.sendNativeMessage가호출되었을 때지정된 response를 callback에 넘겨준다.(아직 제대로 이해하지 못함)

이 경우 native messaging host에 의해 생성된 모든메시지는 무시된다.

 

Connectingto a native application

Native application과 메시지를 주고받는 것은 extension들 간에 메시지를 주고받는 것과 유사하지만 runtime.connect대신runtime.connectNative가 사용되고,runtime.sendMessage대신 runtime.sendNativeMessage가사용된다.

이 메소드들은 extension쪽의 manifest(.json)파일에 nativeMessaging권한이선언되었다면 사용 할 수 있다.

Ex)

"permissions": [

   "nativeMessaging"

  ]

 

아래 예제는 runtime.Port 객체를 생성하고 이 객체는 native messaging host를 com.my_company.my_application으로연결한 후 포트에서 메시지를 읽어오고메시지를 보낸다.

Ex)

var port = chrome.runtime.connectNative(‘com.my_company.my_application’);

port.onMessage.addListner(function(msg){

           console.log(“Received” + msg);

});

port.onDisconnect.addListner(function(){

           console.log(“Disconnected”);

});

port.postMessage({ text: “Hello,my_application”});

 

runtime.sndNativeMessage는 port를 생성하지 않고 native application에 메시지를보내는 것이 가능하다.

EX)

Chrome.runtime.sendNativeMessage(‘com.my_company.my_application’,

           {text : “Hello” },

           Function(response){
                     console.log(“Received” + response);

           }

);

 

Debuggingnative messaging

Native messaging host(.exe)가 실행에 실패한다면, stderr에 쓰이게 되고

Communication protocol에서 문제가 생기면 chrome error log에 출력됨.

 

Linux, OS X에서는 errorlog에 쉽게 접근이 가능하다.

크롬의 커멘드라인 또는 터미널에서 확인할 수 있다.

 

 

결과

결론적으로 1024 x 768이미지를 base64인코딩 하면 1MB정도가 나오는데 최대로 한번에 보낼 수있는 크기가 1MB이기 때문에 여유롭지 못한 점, 100f/s(frameper sec)를 생각하고 있었으나 대부분의 테스트 그림에서는 20f/s정도어떤 그림은 70f/s까지 할때마다 결과가 조금씩 다르게 나왔다안정적이지 못하고 중간에 연결이 끊김

 

실수와 해결책

1.    실수까지는 아니고. Manifest 파일 만들때 태그에 대부분 s가 들어감(ex: scripts) 혹시틀린것 같거나 잘 안돌아간다면 스펠링 확인을 잘 할 것.

2.    App과  host를 잘 구분할 것.

A.    App : 실제로 chrome://extensions에 뜨는 실행부분설치시 코드를찾을 수 있음

B.     Host : 외부 실행 파일(.exe) app 부분의 코드를 호스트 쪽의 json파일에 입력해줘야함.

3.    Install batch (install.bat) 파일에 host의 manifest(.json)파일 위치를 등록하고 app등록 해줘야 하며 이거 실행해서 레지스트리 등록을 완료해야 함다정상이고 에러가 없는데 실행이 안된다거나말도안되게 json파일에서name태그의 이름이 이상하다는 등의 에러가 날 경우 이 문제일 확률이 큼. (Linux, OS X의 경우 .sh)

 

 

References

네이티브 메시지 기본 페이지

https://developer.chrome.com/extensions/nativeMessaging

한번에 보낼 수 있는 메시지 최대 1MB

http://stackoverflow.com/questions/27243529/native-messaging-host-not-able-to-send-1-mb-data

네이티브 메시지 코드

https://code.google.com/p/chromium/codesearch#chromium/src/chrome/browser/extensions/api/messaging/native_message_process_host.cc&sq=package:chromium&q=file:native_message_process_host.cc%20kMaximumMessageSize&l=29



'프로그래밍' 카테고리의 다른 글

[VC 6] Manifest 추가  (0) 2023.01.12
NTFS, FAT와 exFAT에 대 한 기본 클러스터 크기  (0) 2015.07.08
유니티 플랫폼별 경로들  (0) 2015.03.13
윈도우7 SSD 최적화 팁 모음  (0) 2015.02.03