CMake 에서, openCV  쿠다버전을 적용시, 링크 정보를 참고하여, 아키텍쳐 버전 정보를 명시해야 한다.

https://ko.wikipedia.org/wiki/CUDA


명시하지 않을 경우, NCC 가 리얼타임 컴파일을 수행하기 때문에,  시간이 지연되어 실행된다.





:: 설   치.


1. 아래 사이트에서 관련  평가판 다운로드를 신청한다.  

   http://software.intel.com/en-us/intel-integrated-performance-primitives-evaluation-options 가서 접속하여, Get This Library for Free 항목을 클릭한다.



  

   

   

2. 다음 화면에서 다운로드 URL 과 라이센스 키 정보를 받을 이메일 주소와 지역을 입력한 후 SUBMIT 버튼을 클릭한다.






3. 잠시 후, 메일을 확인 한 후, 시리얼 키를 별도로 저장하고, 다운로드 버튼을 클릭하면, 다운로드를 받을 수 있는 사이트로 이동하는데, 여기서 IPP 및 WINDOWS 버전을 각각 선택하고, 다운로드 받는다.



다운로드 받은 후, EXE 파일을 실행하면, 압축을 풀고 계속해서 설치가 진행 된다. 진행 과정에서 시리얼 번호를 입력해야 한다.



*주의사항* 

 설치된 폴더를 다른 곳으로 옮기고, 아래 환경 변수만 변경하면,  라이센스 상관 없이 계속해서 사용할 수 있다.



::환경 설정. 


1. 환경변수 설정. 


  참고:

    1. 실행: 내컴퓨터 속성 -> 고급 시스템 설정-> 고급 탭 -> 환경변수 버튼 클릭. 

    2. 환경 변수를 설정 한 후에는, VC++ 툴을 재시작하거나, 시스탬을 재부팅해야 정상 반영된다. 

    2. 프로그램 기본 설치 경로 : C:\Program files (x86)\IntelSWTools\compilers_and_libraries_2017.x.xxx\<target_os>

  

   

  아래 항목에 대해서, 시스템 변수를 추가한다.

    

   

  - 공통  [변수 : 경로 ]

  1. IPPROOT   :   C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.0.109\windows

  2. IPPINC      :   %IPPROOT%\ipp\include

   

  - WIN32

  3. IPPLIB_WIN32  :  %IPPROOT%\ipp\ia32_win

  4. IPPEXE_WIN32 : %IPPROOT%\redist\ia32_win\ipp


  - X64

  3. IPPLIB_WIN64:  %IPPROOT%\ipp\lib\intel64_win

  4. IPPEXE_WIN64: %IPPROOT%\redist\intel64_win\ipp



 2. VC++ 디렉토리 설정.

    솔류션 프로젝트 속성에서, VC++ Direcotries 항목을 선택하여 아래와 같이 추가한다.


     X86   

    • Include Files $(IPPINC)
    • Library Files $(IPPLIB_WIN32)
    • Executable File $(IPPEXE_WIN32)


 X64   

    • Include Files $(IPPINC)
    • Library Files  $(IPPLIB_WIN64)
    • Executable File $(IPPEXE_WIN64)  



   :: VC++ 샘플 프로그램 실행.


   1. VC++ 를 이용하여 컨솔프로젝트를 생성한다.  


   2.  첨부한 파일을 추가 한다. 
   3.  첨부한 ipp.props 파일을 프로퍼티 매니저를 이용해 추가한다.
   3.  빌드한다. 
   4.  관련 dll 을 작업 디렉토리에 복사한다. 여기서는 ippcore.dll 를 추가하면 된다.
 :: 예제프로그램  경로 및 레퍼런스
   
   - 예제프로그램.
     1. C:\Program files (x86)\IntelSWTools\compilers_and_libraries_2017.x.xxx\<target_os>\ipp\components  로 이동하면, 아래 파일들이 존재한다. 
   
         a. components_and_examples_win_ps.zip
         b. components_and_examples_mic.zip 

      2.  여기서, components_and_examples_win_ps.zip 압축을 푼 후,  components_and_examples_win_ps\components\examples_core 경로로 이동하면,  솔류션 파일을 확인 할 수 있다.

      3. 빌드 가이드는 아래 문서를 참고한다.
        https://software.intel.com/en-us/articles/code-samples-for-intel-integrated-performance-primitives-library#samples_status


   - 레퍼런스. 
     C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2017.0.109\windows\documentation\en\ipp\common\ipp_userguide
      
  
         

   

  

 














NVIDIA Nsight Visual Studio Edition - NVIDIA Documentation [홈] - You Tube


쿠다와 opencv를 이용한 resizing - http://www.coldvision.io/2015/12/22/image-resize-with-opencv-and-cuda/

' > URL' 카테고리의 다른 글

OUTLOOK PLUG IN  (0) 2018.04.04
펌] 각 언어별 딥러닝~ 라이브러리.  (0) 2017.01.17
CUDA  (0) 2016.12.12
GIT 튜토리얼.  (0) 2016.12.08

참조: http://msdn.microsoft.com/en-us/library/bb773559(VS.85).aspx

윈도우의 Visual C++에서 파일 경로를 조작할 때 사용할 수 있는 유용한 API 함수들이다.
사용하기 위해 아래와 같이 선언한다.
#include <shlwapi.h> #pragma comment(lib, "shlwapi")

PathAddBackslash - 경로에 백슬레시를 덧붙여준다. 백슬레시가 이미 붙어 있으면 변경하지 않는다.      

"c:\abc" -> "c:\abc\"
"c:\abc\" -> "c:\abc\"

PathAddExtension - 파일 경로 뒤에 지정된 확장자를 덧붙여준다. 확장자가 이미 있다면 변경하지 않는다.
"c:\abc", ".bak" -> "c:\abc.bak"
"c:\abc.cpp", ".tmp" -> "c:\abc.cpp"

PathAppend - 두 개의 경로를 덧붙인다. 사이에 백슬레시가 없으면 자동으로 추가해 준다.
"c:\abc", "def" -> "c:\abc\def"
"c:\abc\", "def" -> "c:\abc\def"
"c:\abc", "\def" -> "c:\abc\def"
"c:\abc\", "\def" -> "c:\abc\def"

PathBuildRoot - 드라이브 식별번호를 드라이브 경로로 변경해 준다.
0 -> "A:\"
1 -> "B:\"
2 -> "C:\"

PathCanonicalize - 특별한 경로 문자열을 정리해 준다.
"c:\abc\def\..\ghi" -> "c:\abc\ghi"
"c:\abc\def\.\ghi" -> "c:\abc\def\ghi"

PathCombine - 두 개의 경로를 결합한다. 백슬레시도 검사해서 추가하고 ., ..과 같은 특별한 경로 문자열도 정리해 준다.
"c:\abc", "def.txt" -> "c:\abc\def.txt"
"c:\abc\", "..\def\ghi.txt" -> "c:\def\ghi.txt"

PathCommonPrefix -  공통된 경로를 골라낸다.
"c:\abc\def.txt", "c:\abc\ghi\" -> "c:\abc"
"c:\abc\def\jkl.txt", "c:\abc\def\..\jkl.txt" -> "c:\abc\def"

PathCompactPath -  경로를 dc와 pixel 폭 크기에 알맞게 적당히 줄여준다.
hDC, "c:\abc\def\ghi\jkl.txt", 100 -> "c:\abc\...\jkl.txt"

PathCompactPathEx - 경로를 최대 문자열 길이에 알맞게 적당히 줄여준다.
"c:\\abc\\def\\jkl.txt", 15 -> "c:\...\jkl.txt"

PathCreateFromUrl - URL로 쓰여진 파일명을 경로로 변환한다.
"file:///c:/abc/def.txt" -> "c:\abc\def.txt"

PathFileExists - 해당 경로나 파일이 실제로 존재하는지 검사한다.

PathFindExtension - 확장자의 위치를 찾아서 반환한다.
"c:\abc\def.txt" -> ".txt"

PathFindFileName - 파일 이름의 위치를 찾아서 반환한다.
"c:\abc\def.txt -> "def.txt"

PathFindNextComponent - 전체 경로 중 한 단계씩 하위로 내려간 경로를 반환한다.
"c:\abc\def.txt" -> "abc\def.txt"
"abc\def.txt" -> "def.txt"
"def.txt" -> ""

PathFindOnPath - 파일을 찾아서 완전한 경로를 반환한다. (목록이 NULL일 경우 실행 PATH에서 찾기)
"cmd.exe", NULL -> "C:\WINDOWS\system32\cmd.exe"
"iexplore.exe", { "c:\Windows", "c:\Program Files", "c:\Program Files\Internet Explorer", NULL } -> "c:\Program Files\Internet Explorer\iexplore.exe"
파일이 여러개라면 첫번째로 발견된 파일의 경로만 반환

PathFindSuffixArray - 지정된 접미사 목록에서 입력된 경로에 일치하는 것을 찾는다. (대소문자 구분)
"c:\abc\DEF.txt", { "def.txt", "DEF.txt", ".txt" }, 3 -> "DEF.txt"
"c:\abc\def\ghi.txt", { "def.txt", "DEF.txt", ".txt" }, 3 -> ".txt"

PathGetArgs - 전체 문자열에서 앞 단어를 무시한 입력 인자 위치를 찾아서 반환한다.
"test.exe temp.txt sample.doc" -> "temp.txt sample.doc"
"test.exe sample All 15" -> "sample All 15"
"test.exe" -> ""
"abc def ghi" -> "def ghi"

PathGetCharType - 문자가 경로에서 어떤 목적으로 쓰일 수 있는지 확인한다.
':' -> GCT_SEPARATOR
'.' -> GCT_LFNCHAR | GCT_SHORTCHAR
'\\' -> GCT_SEPARATOR
'/' -> GCT_INVALID
'\"' -> GCT_INVALID
'\'' -> GCT_LFNCHAR | GCT_SHORTCHAR
'\t' -> GCT_INVALID
'\n' -> GCT_INVALID
',' -> GCT_LFNCHAR
'*' -> GCT_WILD
'?' -> GCT_WILD
입력된 문자열을 검색하면서 리턴값을 조사하면 올바른 경로인지 미리 검사할 수 있다.

PathGetDriveNumber - 경로가 어느 드라이브에 있는지 번호를 확인한다.
"c:\abc\def.txt" -> 2
"d:" -> 3
"s:\test" -> 18

PathIsContentType - 파일 확장자가 콘텐츠 형식과 일치하는지 확인한다.
"c:\abc\def.txt", "text/plain" -> TRUE
".txt", "text/plain" -> TRUE
"txt", "text/plain" -> FALSE

PathIsDirectory - 실제로 존재하는 폴더인지 확인한다.
"c:\windows" -> TRUE
"c:\abc" -> FALSE

PathIsDirectoryEmpty - 폴더 내부가 비어있는지 확인한다.
"c:\windows" -> FALSE

PathIsFileSpec - 주어진 경로에 경로 문자들이 없는지 확인한다. 결과가 참이라도 올바른 파일명이 아닐 수 있다.
"c:\abc\def.txt" -> FALSE
"test.txt" -> TRUE
"*/wow." -> TRUE

PathIsHTMLFile - 콘텐츠 형식이 "text/html"인 확장자인지 확인한다.
"test.html" -> TRUE
"test.htm" -> TRUE
"test.xml" -> FALSE
"test.txt" -> FALSE

PathIsLFNFileSpec - 주어진 경로가 긴파일이름에 적합한지 확인한다.

PathIsNetworkPath - 주어진 경로가 네트워크 경로 형식인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def.txt" -> FALSE
"\\abc\def.txt" -> TRUE
"http://abc/def.txt" -> FALSE

PathIsPrefix - 경로가 주어진 위치에서 시작하는지 확인한다.
"c:\", "c:\abc" -> TRUE
"C:\", "c:\abc" -> TRUE
"c:", "c:\abc" -> FALSE
"..\abc", "..\abc\def" -> TRUE
"d:\abc", "d:\def" -> FALSE

PathIsRelative - 주어진 경로가 상대 경로인지 확인한다. (파일명만 있어도 상대 경로로 인정)
".\abc.txt" -> TRUE
"..\abc\def.txt" -> TRUE
"c:\abc\def.txt" -> FALSE
"c:\abc\..\def.txt" -> FALSE
"test.txt" -> TRUE

PathIsRoot - 주어진 경로가 드라이브 루트인지 검사한다.
"c:\" -> TRUE
"c:" -> FALSE
"c:\test.txt" -> FALSE

PathIsSameRoot - 주어진 경로가 같은 드라이브에 있는지 검사한다.
"c:\abc\def", "c:\test.txt" -> TRUE

PathIsSystemFolder - 시스템 속성을 가진 폴더인지 확인한다.
"c:\windows" -> FALSE
"c:\program files" -> TRUE
"C:\Documents and Settings" -> FALSE
"C:\Documents and Settings\All Users\Application Data" -> TRUE

PathIsUNC - 네트워크 공유 경로인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def" -> FALSE
"\\abc\def" -> TRUE
"\\192.168.0.1" -> TRUE
"\\abc\def.txt" -> TRUE
"\\" -> TRUE
"\\test.txt" -> TRUE

PathIsUNCServer - 네트워크 공유 서버인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def" -> FALSE
"\\abc\def" -> FALSE
"\\192.168.0.1" -> TRUE
"\\abc\def.txt" -> FALSE
"\\" -> TRUE
"\\test.txt" -> TRUE

PathIsUNCServerShare -  네트워크 공유 폴더인지 확인한다. (실제로 존재하는지 확인하지는 않음)
"c:\abc\def" -> FALSE
"\\abc\def" -> TRUE
"\\192.168.0.1" -> FALSE
"\\abc\def.txt" -> TRUE
"\\" -> FALSE
"\\test.txt" -> FALSE

PathIsURL - 주어진 경로가 URL 형식이 맞는지 확인한다.

PathMakePretty - 대문자로 만들어진 경로 문자열을 소문자로 변환한다. (소문자가 하나라도 있으면 실패)
"C:\ABC\DEF" -> TRUE, "C:\abc\def"
"c:\ABC\DEF" -> FALSE, "c:\ABC\DEF"
"C:\abc\DEF" -> FALSE, "C:\abc\DEF"

PathMakeSystemFolder - 지정된 폴더를 시스템 폴더로 만든다.

PathMatchSpec - 와일드카드 형식으로 파일명과 일치되는지 확인한다.
"test.txt", "*.txt" -> TRUE
"abc.txt", "ab?.*" -> TRUE
"c:\abc\def.txt", "*\???.txt" -> TRUE

PathParseIconLocation - 파일 경로와 아이콘 인덱스 번호를 분리한다.
"iexplore.exe, 1" -> 1, "iexplore.exe"

PathQuoteSpaces - 경로에 공백이 포함되어 있으면 큰따옴표로 묶어준다. 공백이 없으면 무시
c:\1. abc -> "c:\\1. abc"
c:\abc -> c:\abc

PathRelativePathTo - 한 경로에서 다른 경로로 가는 상대 경로를 추출한다. (같은 드라이브에서만 가능)
"c:\abc\def\ghi\jkl.txt", 0, "c:\abc\mno\pqr.txt", 0 -> TRUE, "..\..\mno\pqr.txt"
"c:\abc\def\ghi\jkl", FILE_ATTRIBUTE_DIRECTORY, "c:\abc\mno\pqr.txt", 0
-> TRUE, "..\..\..\mno\pqr.txt"
"c:\abc\def\ghi\jkl.txt", 0, "c:\abc\mno\pqr", FILE_ATTRIBUTE_DIRECTORY
-> TRUE, "..\..\mno\pqr"

PathRemoveArgs - 경로에 포함된 인자를 지운다.
"test.exe temp.txt sample.doc" -> "test.exe"
"test.exe sample All 15" -> "test.exe"
"test.exe" -> "test.exe"
"abc def ghi" -> "abc"

PathRemoveBackslash - 경로 끝에 백슬레시가 있으면 삭제한다.
"c:\abc\" -> "c:\abc"
"c:\abc" -> "c:\abc"

PathRemoveBlanks - 경로 앞뒤에 공백문자가 있으면 삭제한다.
"  c:\abc   " -> "c:\abc"

PathRemoveExtension - 확장자를 삭제한다.
"c:\abc\def.txt" -> "c:\abc\def"

PathRemoveFileSpec - 파일 이름을 삭제한다.
"c:\abc\def.txt" -> "c:\abc"
"c:\abc\def\" -> "c:\abc\def"

PathRenameExtension - 확장자를 교체한다.
"c:\abc\def.txt", ".bak" -> "c:\abc\def.bak"
"c:\abc\def", ".bak" -> "c:\abc\def.bak"
"c:\abc\def\", ".bak" -> "c:\abc\def\.bak"

PathSearchAndQualify - 주어진 경로의 오류를 바로잡고, 상대 경로도 정리하고, 환경 변수도 적용한다.
"C:\foo\." -> "C:\foo"
"C:\foo\baz\.." -> "C:\foo"
"C:\foo\\\baz" -> "C:\foo\baz"
"\\server\aa\..\bb" -> "\\server\aa\bb"
"notepad.exe" -> "C:\Windows\System32\notepad.exe"
"%SystemRoot%\System32\notepad.exe" -> "C:\Windows\System32\notepad.exe"
(XP에서는 환경변수 확장이 제대로 작동하지 않음)

PathSetDlgItemPath - 주어진 다이얼로그 아이템 윈도우의 크기에 알맞게 긴 경로를 적당히 줄여준다.

PathSkipRoot - 루트 경로를 제외한 첫번째 위치를 찾아서 반환한다.
"c:\abc\def" -> "abc\def"
"\\\\abc\\def\\ghi.txt" -> "ghi.txt"

PathStripPath - 가장 마지막 경로만 남기고 삭제한다.
"c:\abc\def.txt" -> "def.txt"
"c:\abc\def" -> "def"
"c:\abc\def\" -> "def\"

PathStripToRoot - 루트 경로만 남기고 삭제한다.
"c:\abc\def.txt" -> "c:\"
"c:\abc\def" -> "c:\"

PathUndecorate - 경로에서 임시 파일에 붙는 숫자를 삭제한다.
"C:\Path\File[5].txt" -> "C:\Path\File.txt"
"C:\Path\File[12]" -> "C:\Path\File"
"C:\Path\File.txt" -> "C:\Path\File.txt"
"C:\Path\[3].txt" -> "C:\Path\[3].txt"
인터넷으로 접근한 임시파일들은 [#]과 같은 식으로 번호가 뒤에 붙는데 그러한 임시 번호를 제거한다.

PathUnExpandEnvStrings - 경로에서 환경 변수에 해당하는 문자열을 환경 변수 이름으로 교체한다.
"c:\Windows\test.txt" -> "%SystemRoot%\test.txt"
"c:\program files\test.txt" -> "%ProgramFiles%\test.txt"
"c:\abc\def" -> "%SystemDrive%\abc\def"

PathUnmakeSystemFolder - 지정된 폴더의 시스템 속성을 해제한다.

PathUnquoteSpaces - 큰 따옴표로 감싸진 경로에서 따옴표를 제거한다.
"c:\abc\1 def" -> c:\abc\1 def
c:\abc\def -> c:\abc\def


' > WIN32 MFC' 카테고리의 다른 글

MFC- APP-VIEW-DOCS 클래스 포인터 가져오기.  (0) 2017.12.21

블루 코드님의 Subversion 사용법입니다.

NASN-321R2, NASN-322R2 에서는 Subverstion 을 add-on 으로 제공하고 있습니다.

-------------------------------------------------------------------------------------------------------------------

Subversion 서버 설치 및 사용법등은 다음 사이트를 참고하세요.

http://www.pyrasis.com/main/Subversion-HOWTO

일단 서버 종료

[root@NASN-321 /mnt/Volume_1/App/subversion]$killall svnserve





메인 repository 로 사용할 디렉토리는 동일하게 repo 라고 생성하고 해당 디렉토리로 이동

[root@NASN-321 /mnt/Volume_1/App/subversion]$mkdir repo

[root@NASN-321 /mnt/Volume_1/App/subversion]$cd repo


작업 폴더 생성

[root@NASN-321 /mnt/Volume_1/App/subversion/repo]$../bin/svnadmin create --fs-type fsfs Test1

다시 서버를 구동.

[root@NASN-321 /mnt/Volume_1/App/subversion/repo]$cd ..

[root@NASN-321 /mnt/Volume_1/App/subversion]$./bin/svnserve -d -r ./repo/



/////////////////// 아래내용대로  Copy And Paste ///////////////////


cd /mnt/Volume_1/App/subversion/repo

killall svnserve

cd ./repo


../bin/svnadmin create --fs-type fsfs  프로젝트명

../bin/svnadmin create --fs-type fsfs  UCFAdvetisementServiceSolution


cd ..

./bin/svnserve -d -r ./repo/

1. MQTT

MQTT는 경량의 Publish/Subscribe(Pub/Sub) 메시징 프로토콜이다. M2M(machine-to-machine)와 IoT(Internet of things)에서의 사용하려고 만들었다. IoT를 위해서 낮은 전력, 낮은 대역폭 환경에서도 사용할 수 있도록 설계됐다.

IoT 관련 일들을 하고 있는데, 저전력/소규모 디바이스를 위한 통신 프로토콜들을 살피면서 자연스럽게 관심을 가지게 됐다.

2. 응용 분야

MQTT는 저전력, 신뢰할 수 없는 네트워크, No TCP/IP 기반에서 운용할 수 있다는 장점이 있다. 소형기기의 제어와 센서정보 수집에 유리하다. 이런 특징들로 특히 IoT 영역에서 주목받고 있다.

2.1. 센서(Sensor) 정보 수집

가전기기, 빌딩, 도시, 산업, 개인 등 다양한 영역에서의 센서정보를 수집할 수 있다. 네트워크 영역으로 보자면 LAN(가정/소규모 오피스), PAN(개인 네트워크), BAN(빌딩 네트워크), MAN(도시영역 네트워크)등에서 사용할 수 있다.

개인적으로 건강과 질병관리 분야에 관심이 간다. 지금 당장 서비스를 개발하기에는 센서장비의 품질 개선이 필요한 것 같다. 지금의 헬스케어 센서들은 "건강한 사람을 위한 악세사리"정도 인것 같다. 이런 용도로 사용하기에는 센서 품질이 별로 중요하지 않겠지만 질병/건강관리를 위해서 본격적으로 사용하려면 품질개선이 필요 할 것 같다.

2.2. 제어

센서로 부터 받은 데이터를 토대로 기기들을 제어할 수 있다. 기기제어 역시 MQTT를 이용하면 된다. 이를 위해서는 각 기기에 MQTT broker를 설치하거나 혹은 중앙에 있는 MQTT broker에 bind할 수 있어야 한다.

2.3. Message Push Server

모바일 애플리케이션을 위한 메시지 Push 서버로 사용 할 수 있다. MQTT의 특징을 살려서 낮은 전력에서 작동하는 Push 서비스를 만들 수 있다. 페이스북의 경우 MQTT를 이용해서 메시지를 push 하고 있다.

3. MQTT 특징

3.1. Publish/Subscribe

MQTT 프로토콜은 메시지를 발행(publishing) 하고, 관심 있는 주제를 구독(subscribe) 하는 것을 기본 원칙으로 한다.

Publisher과 Subscriber은 모두 Broker에 대한 클라이언트로 작동한다. Publisher는 토픽을 발행하기 위한 목적으로 Subscriber은 토픽을 구독하기 위한 목적으로 Broker 서버에 연결한다. 하나 이상의 Pub와 Sub가 브로커에 연결해서 토픽을 발행 하거나 구독할 수 있다. 또한 다수의 클라이언트가 하나의 주제를 구독할 수도 있다.

3.2. 토픽

Pub와 Sub는 토픽을 기준으로 작동한다. 토픽은 슬래시(/)를 이용해서 계층적으로 구성할 수 있어서 대량의 센서 기기들을 효율적으로 관리 할 수 있다. 예를들어 컴퓨터의 다양한 상태를 측정하는 센서가 있다고 다음과 같이 구성할 수 있을 것이다.

3.3. 메시지 버스

MQTT는 메시지 버스 시스템이다. MQTT Broker가 메시지 버스를 만들고 여기에 메시지를 흘려보내면, 버스에 붙은 애플리케이션들이 메시지를 읽어가는 방식이다. 메시지 버스에는 다양한 주제의 메시지들이 흐를 수 있는데, 메시지를 구분하기 위해서 "Topic"을 이름으로 하는 메시지 채널을 만든다.

애플리케이션들은 Message Bus에 연결하고 관심있는 토픽(Topic)을 등록 해서 메시지를 구독(SUB)하거나 발행(PUB)한다.

3.4. QoS

MQTT는 3단계의 QoS(Quality of service)를 제공한다.

  • 0 : 메시지는 한번만 전달하며, 전달여부를 확인하지 않는다. Fire and Forget 타입이다.
  • 1 : 메시지는 반드시 한번 이상 전달된다. 하지만 메시지의 핸드셰이킹 과정을 엄밀하게 추적하지 않기 때문에, 중복전송될 수도 있다.
  • 2 : 메시지는 한번만 전달된다. 메시지의 핸드셰이킹 과정을 추적한다. 높은 품질을 보장하지만 성능의 희생이 따른다.

서비스의 종류에 따라서 적당한 QoS 레벨을 선택해야 한다.

No TCP/IP와 TCP/IP가 섞여있는 로컬 네트워크에서는 QoS 1, 2를 선택하는게 좋을 것 같다. 네트워크 구간을 신뢰할 수 없으며, 메시지 전송이 실패 했을 때, 메시지 박스에 저장하는 일을 하는 소프트웨어 시스템을 구축하기가 쉽지 않기 때문이다.

원격 네트워크에서는 0번이 좋을 것 같다. QoS 1이 적당할 것 같지만, 1이나 2를 선택할 경우 메시지 관리가 힘들어진다. 예를들어 offline 모드에서의 메시징을 지원하기 위해서 메시지 박스 서비스를 제공한다고 가정해 보자. QoS 1로 설정을 하면, 다음 연결에 메시지를 보내기 위해서 자체 queue에 저장을 한다. 그러면 시스템 입장에서는 MQTT queue에 있는 메시지를 읽어야 하는데, 메시지 박스에서 읽어야 하는지를 판단해야 한다.

또한 클라이언트는 MQTT queue에 있는 메시지를 읽기 위해서 이전에 연결했던 MQTT에 연결을 해야 하는데, 이러한 요구사항은 클러스터 구성을 어렵게 한다. 설계 관점에서도 비슷한 일을 하는 두 개의 모듈을 두는 것은 좋지 않은 설계다. 그냥 QoS 레벨은 0으로 하고, 소프트웨어에서 QoS를 처리하는게 깔끔할 것 같다.

4. MQTT 브로커들

MQTT 서버라고 하지 않고 중개인(브로커)라고 하는 이유는 MQTT가 발행인과 구독자가 메시지를 주고 받을 수 있도록 다리를 놔주는 역할만을 하기 때문이다. 다른 기능들은 중계를 도와주는 부가 기능일 뿐이다. 다양한 종류의 브로커들이 있는데, 여기에서 확인하자.

내가 경험한 브로커들만 간단히 정리한다.

4.1. Mosquitto MQTT broker

모스키토(Mosquitto)는 (2014년 6월 현재)MQTT 프로토콜 3.1을 구현한 BSD 라이센스 기반의 오픈소스 메시지 브로커다. 나는 모스키토를 이용해서 PUB,SUB,Broker 테스트를 진행하기로 했다.

4.1.1. 테스트 환경

  • VirtualBox를 이용해서 PUB, SUB, Broker를 위한 3개의 게스트 운영체제를 실행했다. 호스트 이름은 각각 pub.local, sub.local, broker.local 이다.
  • 게스트 운영체제 : 우분투 리눅스 14.04로 통일

4.1.2. Mosquitto 브로커 설치

1
broker.local # apt-get install mosquitto

설치가 끝나면 바로 bind 된다.

1
2
3
broker.local # netstat -nap | grep mosquitto
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 1512/mosquitto
tcp6 0 0 :::1883 :::* LISTEN 1512/mosquitto

4.1.3. Mosquitto 클라이언트 설치

모스키토 클라이언트 프로그램을 설치했다.

1
# apt-get install mosquitto-clients

4.1.4. Pub/Sub 테스트

hello/world 토픽을 subscribing 한다.

1
2
3
4
# mosquitto_sub -d -t hello/world
Received CONNACK
Received SUBACK
Subscribed (mid: 1): 0

hello/world토픽에 Publishing을 했다.

1
2
3
# mosquitto_pub -d -t hello/world -m "Hello World"
Received CONNACK
Sending PUBLISH (d0, q0, r0, m1, 'hello/world', ... (11 bytes))

Sub 클라이언트는 "Hello World"를 전송 받는다.

modquitto_sub를 하나 더 실행 한다음 "Hello World"를 publishing 해보자. 토픽에 subscribing한 모든 클라이언트에 메시지가 전달되는 걸 확인할 수 있다.

4.1.5. 장점과 단점

MQTT 전용 브로커로 매우 가벼우며, MQTT 브로커가 가져야 할 대부분의 기능을 충실히 지원한다는 장점이 있다. 소형기기에 올려서 사용하기에 적당하다.

()현재 최신 안정 버전 1.3.5는 아직 WebSocket을 지원하지 않는다. 1.4에서 지원하는데, 지금은 직접 빌드해서 사용해야 한다. 클러스터를 지원하지 않는 것도 단점이다. 대규모의 메시징 시스템을 구축하려면 노가다를 뛰어야 한다. 메시징 서비스 인프라에 고가용성은 필수 요소이기 때문에 중요한 문제가 될 수 있다.

4.2. RabbitMQ

AMQP를 지원하는 메시지 큐 서버로 플러그인(Plug-in)방식으로 MQTT를 지원한다. AMQP를 이용한 범용 메시징 서버라서 좀 무겁기는 하지만 클러스터링을 지원하고 다양한 플러그인을 이용해서 기능을 확장할 수 있다. STOMP, 웹 소켓HTTP(S)등 다양한 통신 프로토콜을 지원하기 때문에, 메시징 서버 인프라의 개발에 적당하다.

4.2.1. MQTT Plugin 실행

RabbitMQ를 설치하면 20개 정도의 플러그인들도 함께 깔린다. rabbitmq-plugins를 이용해서 간단하게 mqtt를 올릴 수 있다.

1
2
3
4
5
# rabbitmq-plugins enable rabbitmq_mqtt
The following plugins have been enabled:
amqp_client
rabbitmq_mqtt
Plugin configuration has changed. Restart RabbitMQ for changes to take effect.

4.2.2. 장점과 단점

RabbitMQ는 범용 메시징 서버로 다양한 메시징 방식을 제공한다. AMQP, MQTT 프로토콜을 지원하며 HTTP(S), STOMP, 웹소켓, JSONRPC 등의 다양한 통신 방식을 지원한다. 다양한 활용이 가능하다는 것은 장점이라고 볼 수 있겠는데, 기능이 많은 만큼 무겁다. 자원이 빈약한 소형기기에 사용하기에는 무리가 있다. 메시징 인프라 구축에는 RabbitMQ, 소형기기의 메시징 브로커로는 모스키토의 사용을 고려해 봄직하다.

4.3. 메시징 서비스 인프라 제안

서비스 마다 달라질 수 있겠다. IoT를 기준으로 제안한다.

서버 인프라는 가용성과 확장성이 유리한 RabbitMQ로 구축한다. 모스키토로도 구축할 수 있기는 하지만 노가다를 뛰어야 한다. 기타 보안, 인증, 다양한 프로토콜 지원, 플러그인 개발 등을 고려해보면 RabbitMQ를 선택해야 할 것 같다.

기기들은 모스키토를 이용한다. 가볍고 간단해서 소형기기에 집어 넣기에 적당하다.

5. Chatting 프로그램

MQTT를 이용한 Pub/Sub 테스트는 끝냈으니, 이제 좀 그럴 듯한 서비스를 만들어봐야 겠다. MQTT를 이용한 chatting 프로그램을 개발할려고 한다. 이 chatting 프로그램은 아래의 기능을 지원한다.

  • 채팅방 생성 : 채팅방을 Topic으로 하면 된다. Topic을 늘리는 것으로 여러 개의 채팅방을 운용할 수도 있을 거다. 채팅방을 임의로 만들게 하는 건 귀찮으니.. 그냥 "chat/public", "chat/private" 두개의 채팅방만 만들기로 했다.
  • 채팅방 Join : 원래는 채팅방 목록을 확인해서 Join해야겠으나 귀찮으니, chat/public, chat/private 모두를 sub 하는 걸로 join을 대신하겠다. 유저는 nickname을 만들어서 두개의 topic에서 메시지를 받아본다. 채팅 클라이언트 프로그램은 Sub와 Pub를 모두 해야 하니 멀티 쓰레드로 작동해야 한다.

    1. MQTT 브로커로는 앞서 다룬 모스키토를 사용했다.
    2. 쓰레드 하나는 Sub 전용이다. 토픽으로 받은 정보를 화면에 출력한다.
      • chat/public : 공개 채널의 메시지를 받기 위해서 사용한다.
      • chat/public/nickname : 자신의 nicname 토픽에 메시지를 받기 위함.
    3. 쓰레드 하나는 Pub 전용이다. 표준입력을 토픽에 publishing 한다.
      • chat/public : 공개 채널에 publishing 한다.
    4. chat/public/other : 특정 유저에게 publishing 하기 위해서 사용한다
    펌] http://www.joinc.co.kr/w/man/12/MQTT/Tutorial


    'IT 토픽 ' 카테고리의 다른 글

    C++/WinRT  (0) 2016.12.28

    + Recent posts