NATS 메시징 시스템용 AC 클라이언트입니다.
온라인 설명서를 보려면 여기로 이동하여 자주 묻는 질문을 확인하세요.
이 NATS 클라이언트 구현은 NATS GO 클라이언트를 기반으로 합니다. Mac OS/X, Linux 및 Windows를 지원합니다(특정 플랫폼 지원 매트릭스는 없지만).
NATS C 클라이언트 라이브러리를 사용할 수 있는 여러 패키지 관리자가 있습니다. 이 목록에 없는 것을 알고 있다면 PR을 제출하여 추가하세요!
먼저 소스 코드를 다운로드합니다.
git clone [email protected]:nats-io/nats.c.git .
라이브러리를 빌드하려면 CMake를 사용하세요. 기본적으로 NATS Streaming API는 NATS 라이브러리에 구축되어 포함됩니다. 스트리밍 관련 API를 빌드하지 않으려면 아래를 참조하세요.
CMake가 경로에 추가되었는지 확인하세요. Windows에서 빌드하는 경우 Visual Studio 도구 메뉴에서 명령 셸을 열고 적절한 명령 셸(64비트 또는 32비트 빌드의 경우 각각 x64 또는 x86)을 선택합니다. 또한 관리자 권한으로 실행해야 할 수도 있습니다.
루트 소스 트리에서 build
디렉터리(어떤 이름이든 가능)를 만들고 그 cd
로 들어갑니다. 그런 다음 처음으로 다음 명령을 실행하십시오.
cmake ..
일부 아키텍처에서는 잠금을 획득하려고 회전할 때 생성하는 데 사용하는 어셈블러 명령이 지원되지 않기 때문에 mutex.co
에 대한 컴파일 오류가 발생할 수 있습니다.
다음과 같은 빌드 오류가 발생할 수 있습니다.
/tmp/cc1Yp7sD.s: Assembler messages:
/tmp/cc1Yp7sD.s:302: Error: selected processor does not support ARM mode `yield'
src/CMakeFiles/nats_static.dir/build.make:542: recipe for target 'src/CMakeFiles/nats_static.dir/unix/mutex.c.o' failed
이 경우 NATS_BUILD_NO_SPIN
플래그를 활성화하여 이 문제를 해결할 수 있습니다(또는 CMake 없이 컴파일하는 경우 -DNATS_NO_SPIN
사용).
cmake .. -DNATS_BUILD_NO_SPIN=ON
이전에 라이브러리를 빌드한 경우 make clean
수행하거나 cmake 명령을 실행하기 전에 빌드 디렉터리를 삭제하고 다시 생성해야 할 수도 있습니다.
Windows에서 빌드하려면 빌드 생성기를 선택해야 합니다. 예를 들어 nmake
선택하려면 다음을 실행합니다.
cmake .. -G "NMake Makefiles"
cmake -h
실행하면 가능한 옵션 목록과 모든 생성기 이름이 제공됩니다.
또는 GUI 버전을 실행할 수 있습니다. 동일한 빌드 명령 셸에서 GUI를 시작합니다.
c:program files (x86)CMakebincmake-gui.exe
빈 빌드 디렉터리로 시작한 경우 소스 및 빌드 디렉터리를 선택한 다음 Configure
클릭해야 합니다. 여기서는 드롭다운 상자에서 빌드 생성기의 이름을 선택할 수 있습니다. 완료되면 Generate
클릭합니다. 그런 다음 명령 셸이나 Visual Studio로 돌아가서 빌드할 수 있습니다.
일부 빌드 옵션을 수정하려면 캐시를 편집하고 다시 빌드해야 합니다.
make edit_cache
Windows에서 빌드하고 "NMake Makefiles"를 선택한 경우 make
에 대한 다음 참조를 모두 nmake
로 바꾸십시오.
캐시를 편집하면 빌드 유형(디버그, 릴리스 등), 아키텍처(64 또는 32비트) 등을 선택할 수 있습니다.
기본 대상은 모든 것, 즉 정적 및 공유 NATS 라이브러리와 예제 및 테스트 프로그램을 빌드합니다. 각각은 빌드 디렉터리 src
, examples
및 test
아래의 해당 디렉터리에 있습니다.
make install
install/lib
폴더의 정적 및 공유 라이브러리와 install/include
의 공개 헤더를 모두 복사합니다.
기본적으로 라이브러리는 TLS 지원으로 구축됩니다. cmake gui make edit_cache
에서 이를 비활성화하고 NATS_BUILD_WITH_TLS
옵션을 OFF
로 전환하거나 해당 옵션을 cmake
명령에 직접 전달할 수 있습니다.
cmake .. -DNATS_BUILD_WITH_TLS=OFF
2.0.0
부터 TLS/SSL 지원으로 빌드할 때 서버 인증서의 예상 호스트 이름이 항상 확인됩니다. 이는 URL 또는 natsOptions_SetExpectedHostname()
옵션을 통해 제공된 호스트 이름이 인증서에 있는 호스트 이름을 확인하는 데 사용된다는 의미입니다. 2.0.0
이전에는 natsOptions_SetExpectedHostname()
옵션이 호출된 경우 에만 호스트 이름이 확인되었습니다.
새로운 기본 동작을 그대로 두는 것이 좋지만 이 옵션을 끄고 라이브러리를 빌드하면 이전 동작을 복원할 수 있습니다.
cmake .. -DNATS_BUILD_TLS_FORCE_HOST_VERIFY=OFF
NATS C 클라이언트는 OpenSSL 라이브러리의 API를 사용하여 구축되었습니다. 기본적으로 우리는 3.0+
API를 사용합니다. OpenSSL 1.0.2
더 이상 지원되지 않으므로 NATS C 클라이언트 v3.6.0
버전부터 CMake 변수 NATS_BUILD_TLS_USE_OPENSSL_1_1_API
이제 기본적으로 ON
으로 설정되며(새 환경을 설정하는 경우) 1.1+
/ 3.0+
API. 이 CMake 옵션을 OFF
로 설정하면 OpenSSL 1.0.2
라이브러리로 계속 컴파일할 수 있습니다.
cmake .. -DNATS_BUILD_TLS_USE_OPENSSL_1_1_API=OFF
NATS_BUILD_TLS_USE_OPENSSL_1_1_API
변수는 더 이상 사용되지 않습니다. 즉, 앞으로는 이 옵션이 제거되고 OpenSSL 3.0+
API만 사용됩니다. 이전 OpenSSL API를 사용하는 라이브러리의 코드도 제거됩니다.
v2.0.0
에서 더 이상 사용되지 않는 변수 NATS_BUILD_WITH_TLS_CLIENT_METHOD
가 이제 제거되었습니다.
NATS C 클라이언트는 OpenSSL 라이브러리에 동적으로 연결되므로 OpenSSL 1.1+/3.0+ 라이브러리에 대해 애플리케이션을 실행하고 있는지 확인해야 합니다.
정적 OpenSSL 라이브러리에 연결하려면 CMakeCache.txt
를 삭제하고 추가 옵션을 사용하여 다시 생성해야 합니다.
rm CMakeCache.txt
cmake .. -DNATS_BUILD_OPENSSL_STATIC_LIBS=ON
그런 다음 make
(또는 플랫폼에 따라 이에 상응하는 항목)를 호출하면 라이브러리(및 예제 및/또는 테스트 스위트 실행 파일)가 CMake에서 발견된 경우 OpenSSL 라이브러리에 대해 연결되는지 확인해야 합니다.
스트리밍 지원으로 라이브러리를 빌드할 때 NATS 라이브러리는 libprotobuf-c 라이브러리를 사용합니다. cmake가 처음 실행될 때(또는 CMakeCache.txt
제거하고 cmake ..
다시 호출한 후) libprotobuf-c 라이브러리를 찾습니다. 찾지 못하면 메시지가 인쇄되고 빌드 프로세스가 실패합니다. CMake는 라이브러리가 일반적으로 발견되는 디렉터리에서 라이브러리를 검색합니다. 그러나 라이브러리가 있는 특정 디렉터리를 지정하려면 다음을 수행해야 합니다.
cmake .. -DNATS_PROTOBUF_DIR=
기본적으로 정적 라이브러리가 사용됩니다. 이를 변경하고 싶거나 라이브러리에 예상 이름이 없는 경우 다음을 수행해야 합니다.
# Use the library named mylibproto.so located at /my/location
cmake .. -DNATS_PROTOBUF_LIBRARY=/my/location/mylibproto.so
포함 헤더가 다른 디렉토리에 있는 경우 두 개를 결합할 수 있습니다.
# Use the library named mylibproto.so located at /my/location and the directory protobuf-c/ containing protobuf-c.h located at /my/other/location
cmake .. -DNATS_PROTOBUF_LIBRARY=/my/location/mylibproto.so -DNATS_PROTOBUF_DIR=/my/other/location
NATS 라이브러리에 포함될 NATS 스트리밍 API를 빌드하지 않으려는 경우:
cmake .. -DNATS_BUILD_STREAMING=OFF
새로운 NATS 2.0 보안 기능을 사용할 때 라이브러리는 연결 또는 재연결 중에 서버에서 보낸 일부 "nonce"에 서명해야 합니다. 우리는 Ed25519 공개 키 서명을 사용합니다. 라이브러리에는 서명을 수행하기 위한 일부 코드가 함께 제공됩니다. 대부분의 경우 괜찮지만 성능이 문제인 경우(특히 natsConnection_Sign()
함수를 많이 사용할 계획인 경우) Libsodium 라이브러리를 사용하여 빌드할 수 있는 옵션이 있습니다.
여기에서 libsodium 라이브러리를 설치하는 방법에 대한 지침을 따르세요.
macOS에서는 brew
사용할 수 있습니다.
brew install libsodium
Linux에서는 apt-get
사용할 수 있습니다.
apt-get install libsodium-dev
설치한 후에는 먼저 libsodium 라이브러리 사용을 활성화하여 NATS C 클라이언트를 다시 빌드할 수 있습니다.
cmake .. -DNATS_BUILD_USE_SODIUM=ON
CMake가 찾을 수 없는 비표준 위치에 libsodium 라이브러리가 설치된 경우 이 디렉터리의 위치를 지정할 수 있습니다.
cmake .. -DNATS_BUILD_USE_SODIUM=ON -DNATS_SODIUM_DIR=/my/path/to/libsodium
valgrind
사용할 수 있는 플랫폼에서는 메모리 검사를 통해 테스트를 실행할 수 있습니다. 예는 다음과 같습니다.
make test ARGS="-T memcheck"
또는 ctest
프로그램을 직접 호출할 수 있습니다.
ctest -T memcheck -V -I 1,4
위 명령은 valgrind
( -T memcheck
), 자세한 출력( -V
)을 사용하여 테스트를 실행하고 1부터 4( -I 1,4
)까지 테스트를 실행합니다.
test/test.c
에 테스트를 추가하는 경우 list_test.txt
파일에 추가해야 합니다. 각 항목에는 테스트 이름만 포함되며, 함수 이름은 test_
접두사를 사용하여 동일하게 지정해야 합니다. 목록은 알파벳 순서로 되어 있지만 반드시 그럴 필요는 없으며 어디에든 추가할 수 있습니다.
벤치마크를 추가하는 경우 list_bench.txt
에 추가해야 합니다. 이러한 테스트는 다르게 레이블이 지정되며( -L 'bench'
) CI에서 별도로 실행됩니다.
변경 사항을 적용하려면 cmake
다시 실행해야 합니다.
cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ivan/nats.c/build
다음 환경 변수를 사용하여 테스트 스위트 동작에 영향을 줄 수 있습니다.
메모리 검사를 실행하면 타이밍이 변경되고 전반적인 성능이 느려집니다. 다음 변수를 사용하면 테스트 스위트가 테스트 중에 사용되는 일부 값을 조정할 수 있습니다.
export NATS_TEST_VALGRIND=yes
Windows에서는 export
대신 set
됩니다.
상세 모드에서 테스트를 실행할 때 다음 환경 변수를 사용하면 테스트 자체 내에서 서버 출력을 볼 수 있습니다. 이 옵션이 없으면 서버 출력이 조용해집니다.
export NATS_TEST_KEEP_SERVER_OUTPUT=yes
기본 서버 실행 파일 이름( nats-server.exe
)을 변경하거나 특정 위치를 지정하려면 다음 환경 변수를 사용하세요.
set NATS_TEST_SERVER_EXE=c:testnats-server.exe
공개 API는 Doxygen을 사용하여 문서화되었습니다.
문서를 생성하려면 doc
디렉터리로 이동하여 다음 명령을 입력하세요.
doxygen DoxyFile.NATS.Client
스트리밍 API의 빌드를 전환하고 문서가 더 이상 빌드 중인 내용과 일치하지 않는 경우 NATS_UPDATE_DOC
빌드 플래그를 전환하여 문서를 업데이트하고 문서를 다시 빌드할 수 있습니다.
빌드 디렉터리에서:
cmake .. -DNATS_UPDATE_DOC=ON
make
cd /doc
doxygen DoxyFile.NATS.Client
생성된 문서는 html
디렉토리에 위치합니다. 설명서를 보려면 브라우저에서 해당 디렉터리의 index.html
파일을 가리키세요.
온라인 문서를 보려면 여기로 이동하세요.
소스 코드도 상당히 문서화되어 있습니다.
이 섹션에는 지원 중단 알림 등과 같은 중요한 변경 사항이 나열되어 있습니다.
2.0.0
이 버전은 NATS Server 2.0.0
에서 사용되는 보안 개념을 도입하므로 서버 버전과 일치합니다. 새로운 API가 도입되었지만 가장 중요한 변경 사항은 TLS 연결의 새로운 기본 동작입니다.
보안 연결을 설정할 때 이제 사용자가 natsOptions_SetExpectedHostname()
호출했는지 여부에 관계없이 서버 인증서의 호스트 이름이 항상 확인됩니다. 이로 인해 예를 들어 인증서에 호스트 이름만 있는 서버에 연결하기 위해 IP를 사용하는 애플리케이션이 중단될 수 있습니다. 이 문제는 URL의 호스트 이름을 사용하거나 natsOptions_SetExpectedHostname()
을 사용하도록 애플리케이션을 변경하여 해결할 수 있습니다. 이것이 가능하지 않은 경우 새 동작을 비활성화한 상태로 라이브러리를 빌드하여 이전 동작을 복원할 수 있습니다. 자세한 내용은 #tls-support를 참조하세요.
이 저장소는 헤더 파일( /pbuf
디렉터리에 있음)과 함께 macOS, Linux 및 Windows용 사전 컴파일된 libprotobuf-c 라이브러리를 포함하는 데 사용되었습니다. 이제 이 디렉터리를 제거했으며 사용자가 libprotobuf-c 라이브러리를 별도로 설치해야 합니다. CMake가 라이브러리 위치를 직접 찾을 수 없는 경우 라이브러리 위치를 지정하려면 빌드 지침을 참조하세요.
1.8.0
natsConnStatus
열거형 값에는 NATS_CONN_STATUS_
접두사가 붙었습니다. 애플리케이션이 CONNECTED
또는 CLOSED
등과 같은 원래 값 참조를 사용하지 않는 경우에는 수행할 작업이 없습니다. 그렇다면 두 가지 옵션이 있습니다.NATS_BUILD_NO_PREFIX_CONNSTS
옵션을 설정합니다. 이 작업은 빌드 디렉터리에서 다음과 같이 수행할 수 있습니다. cmake .. -DNATS_BUILD_NO_PREFIX_CONNSTS=ON
examples/getstarted
디렉토리에는 완벽하게 작동하면서도 매우 간단한 간단한 예제 세트가 있습니다. 목표는 API를 사용하는 것이 얼마나 쉬운지 보여주는 것입니다.
더 복잡한 예제 세트는 examples/
디렉토리에 있으며 클라이언트 라이브러리를 벤치마킹하는 데에도 사용할 수 있습니다.
단순화를 위해 여기서는 오류 검사가 수행되지 않습니다.
natsConnection * nc = NULL ;
natsSubscription * sub = NULL ;
natsMsg * msg = NULL ;
// Connects to the default NATS Server running locally
natsConnection_ConnectTo ( & nc , NATS_DEFAULT_URL );
// Connects to a server with username and password
natsConnection_ConnectTo ( & nc , "nats://ivan:secret@localhost:4222" );
// Connects to a server with token authentication
natsConnection_ConnectTo ( & nc , "nats://myTopSecretAuthenticationToken@localhost:4222" );
// Simple publisher, sending the given string to subject "foo"
natsConnection_PublishString ( nc , "foo" , "hello world" );
// Publish binary data. Content is not interpreted as a string.
char data [] = { 1 , 2 , 0 , 4 , 5 };
natsConnection_Publish ( nc , "foo" , ( const void * ) data , 5 );
// Simple asynchronous subscriber on subject foo, invoking message
// handler 'onMsg' when messages are received, and not providing a closure.
natsConnection_Subscribe ( & sub , nc , "foo" , onMsg , NULL );
// Simple synchronous subscriber
natsConnection_SubscribeSync ( & sub , nc , "foo" );
// Using a synchronous subscriber, gets the first message available, waiting
// up to 1000 milliseconds (1 second)
natsSubscription_NextMsg ( & msg , sub , 1000 );
// Destroy any message received (asynchronously or synchronously) or created
// by your application. Note that if 'msg' is NULL, the call has no effect.
natsMsg_Destroy ( msg );
// Unsubscribing
natsSubscription_Unsubscribe ( sub );
// Destroying the subscription (this will release the object, which may
// result in freeing the memory). After this call, the object must no
// longer be used.
natsSubscription_Destroy ( sub );
// Publish requests to the given reply subject:
natsConnection_PublishRequestString ( nc , "foo" , "bar" , "help!" );
// Sends a request (internally creates an inbox) and Auto-Unsubscribe the
// internal subscriber, which means that the subscriber is unsubscribed
// when receiving the first response from potentially many repliers.
// This call will wait for the reply for up to 1000 milliseconds (1 second).
natsConnection_RequestString ( & reply , nc , "foo" , "help" , 1000 );
// Closing a connection (but not releasing the connection object)
natsConnection_Close ( nc );
// When done with the object, free the memory. Note that this call
// closes the connection first, in other words, you could have simply
// this call instead of natsConnection_Close() followed by the destroy
// call.
natsConnection_Destroy ( nc );
// Message handler
void
onMsg ( natsConnection * nc , natsSubscription * sub , natsMsg * msg , void * closure )
{
// Prints the message, using the message getters:
printf ( "Received msg: %s - %.*sn" ,
natsMsg_GetSubject ( msg ),
natsMsg_GetDataLength ( msg ),
natsMsg_GetData ( msg ));
// Don't forget to destroy the message!
natsMsg_Destroy ( msg );
}
JetStream에 대한 지원은 라이브러리 버전 v3.0.0
및 NATS 서버 v2.2.0+
부터 시작됩니다. 하지만 JetStream 특정 오류 코드를 얻으려면 버전 v2.3.0+
의 서버가 필요합니다. 일부 구성 옵션은 v2.3.3
부터만 사용할 수 있으므로 더 나은 경험을 위해서는 최신 NATS 서버 릴리스를 사용하는 것이 좋습니다.
API 사용 방법에 대한 예제는 examples
디렉터리에 있는 js-xxx.c
라는 예제를 참조하세요. 새로운 개체와 API는 온라인 설명서에 전체 설명되어 있습니다.
// Connect to NATS
natsConnection_Connect ( & conn , opts );
// Initialize and set some JetStream options
jsOptions jsOpts ;
jsOptions_Init ( & jsOpts );
jsOpts . PublishAsync . MaxPending = 256 ;
// Create JetStream Context
natsConnection_JetStream ( & js , conn , & jsOpts );
// Simple Stream Publisher
js_Publish ( & pa , js , "ORDERS.scratch" , ( const void * ) "hello" , 5 , NULL , & jerr );
// Simple Async Stream Publisher
for ( i = 0 ; i < 500 ; i ++ )
{
js_PublishAsync ( js , "ORDERS.scratch" , ( const void * ) "hello" , 5 , NULL );
}
// Wait for up to 5 seconds to receive all publish acknowledgments.
jsPubOptions_Init ( & jsPubOpts );
jsPubOpts . MaxWait = 5000 ;
js_PublishAsyncComplete ( js , & jsPubOpts );
// One can get the list of all pending publish async messages,
// to either resend them or simply destroy them.
natsMsgList pending ;
s = js_PublishAsyncGetPendingList ( & pending , js );
if ( s == NATS_OK )
{
int i ;
for ( i = 0 ; i < pending . Count ; i ++ )
{
// There could be a decision to resend these messages or not.
if ( your_decision_to_resend ( pending . Msgs [ i ]))
{
// If the call is successful, pending.Msgs[i] will be set
// to NULL so destroying the pending list will not destroy
// this message since the library has taken ownership back.
js_PublishMsgAsync ( js , & ( pending . Msgs [ i ]), NULL );
}
}
// Destroy the pending list object and all messages still in that list.
natsMsgList_Destroy ( & pending );
}
// To create an asynchronous ephemeral consumer
js_Subscribe ( & sub , js , "foo" , myMsgHandler , myClosure , & jsOpts , NULL , & jerr );
// Same but use a subscription option to ask the callback to not do auto-ack.
jsSubOptions so ;
jsSubOptions_Init ( & so );
so . ManualAck = true;
js_Subscribe ( & sub , js , "foo" , myMsgHandler , myClosure , & jsOpts , & so , & jerr );
// Or to bind to an existing specific stream/durable:
jsSubOptions_Init ( & so );
so . Stream = "MY_STREAM" ;
so . Consumer = "my_durable" ;
js_Subscribe ( & sub , js , "foo" , myMsgHandler , myClosure , & jsOpts , & so , & jerr );
// Synchronous subscription:
js_SubscribeSync ( & sub , js , "foo" , & jsOpts , & so , & jerr );
jsStreamConfig cfg ;
// Connect to NATS
natsConnection_Connect ( & conn , opts );
// Create JetStream Context
natsConnection_JetStream ( & js , conn , NULL );
// Initialize the configuration structure.
jsStreamConfig_Init ( & cfg );
// Provide a name
cfg . Name = "ORDERS" ;
// Array of subjects and its size
cfg . Subjects = ( const char * [ 1 ]){ "ORDERS.*" };
cfg . SubjectsLen = 1 ;
// Create a Stream. If you are not interested in the returned jsStreamInfo object,
// you can pass NULL.
js_AddStream ( NULL , js , & cfg , NULL , & jerr );
// Update a Stream
cfg . MaxBytes = 8 ;
js_UpdateStream ( NULL , js , & cfg , NULL , & jerr );
// Delete a Stream
js_DeleteStream ( js , "ORDERS" , NULL , & jerr );
실험적인 기능! 우리는 라이브러리의 주요 버전을 변경하지 않고도 API를 변경할 권리를 보유합니다.
KeyValue 저장소는 JetStream을 기반으로 한 구체화된 뷰입니다. 버킷은 스트림이고 키는 해당 스트림 내의 주제입니다.
일부 기능에는 NATS 서버 v2.6.2
가 필요하므로 더 나은 환경을 위해서는 최신 NATS 서버 릴리스를 사용하는 것이 좋습니다.
새로운 개체와 API는 온라인 설명서에 전체 설명되어 있습니다.
KeyValue 저장소를 만드는 방법의 예:
jsCtx * js = NULL ;
kvStore * kv = NULL ;
kvConfig kvc ;
// Assume we got a JetStream context in `js`...
kvConfig_Init ( & kvc );
kvc . Bucket = "KVS" ;
kvc . History = 10 ;
s = js_CreateKeyValue ( & kv , js , & kvc );
// Do some stuff...
// This is to free the memory used by `kv` object,
// not delete the KeyValue store in the server
kvStore_Destroy ( kv );
이는 기존 항목에 "바인딩"하는 방법을 보여줍니다.
jsCtx * js = NULL ;
kvStore * kv = NULL ;
// Assume we got a JetStream context in `js`...
s = js_KeyValue ( & kv , ks , "KVS" );
// Do some stuff...
// This is to free the memory used by `kv` object,
// not delete the KeyValue store in the server
kvStore_Destroy ( kv );
서버에서 KeyValue 저장소를 삭제하는 방법은 다음과 같습니다.
jsCtx * js = NULL ;
// Assume we got a JetStream context in `js`...
s = js_DeleteKeyValue ( js , "KVS" );
특정 키에 값을 입력하는 방법은 다음과 같습니다.
kvStore * kv = NULL ;
uint64_t rev = 0 ;
// Assume we got a kvStore...
s = kvStore_PutString ( & rev , kv , "MY_KEY" , "my value" );
// If the one does not care about getting the revision, pass NULL:
s = kvStore_PutString ( NULL , kv , "MY_KEY" , "my value" );
위의 코드는 주어진 키에 대한 값을 배치하지만, 그 대신 이전에 존재하지 않았던 키에 대한 값만 배치되도록 하려면 다음을 호출합니다.
// Same note than before: if "rev" is not needed, pass NULL:
s = kvStore_CreateString ( & rev , kv , "MY_KEY" , "my value" );
서버의 마지막 개정판이 이 API에 전달된 개정판과 일치하는 경우에만 키를 업데이트할 수 있습니다.
// This would update the key "MY_KEY" with the value "my updated value" only if the current revision (sequence number) for this key is 10.
s = kvStore_UpdateString ( & rev , kv , "MY_KEY" , "my updated value" , 10 );
열쇠를 얻는 방법은 다음과 같습니다.
kvStore * kv = NULL ;
kvEntry * e = NULL ;
// Assume we got a kvStore...
s = kvStore_Get ( & e , kv , "MY_KEY" );
// Then we can get some fields from the entry:
printf ( "Key value: %sn" , kvEntry_ValueString ( e ));
// Once done with the entry, we need to destroy it to release memory.
// This is NOT deleting the key from the server.
kvEntry_Destroy ( e );
키를 제거하는 방법은 다음과 같습니다.
kvStore * kv = NULL ;
// Assume we got a kvStore...
s = kvStore_Purge ( kv , "MY_KEY" );
그러면 서버의 키가 삭제됩니다.
kvStore * kv = NULL ;
// Assume we got a kvStore...
s = kvStore_Delete ( kv , "MY_KEY" );
특정 키에 대한 "감시자"를 생성하려면:
kvWatcher * w = NULL ;
kvWatchOptions o ;
// Assume we got a kvStore...
// Say that we are not interested in getting the
// delete markers...
// Initialize a kvWatchOptions object:
kvWatchOptions_Init ( & o );
o . IgnoreDeletes = true;
// Create the watcher
s = kvStore_Watch ( & w , kv , "foo.*" , & o );
// Check for error..
// Now get updates:
while ( some_condition )
{
kvEntry * e = NULL ;
// Wait for the next update for up to 5 seconds
s = kvWatcher_Next ( & e , w , 5000 );
// Do something with the entry...
// Destroy to release memory
kvEntry_Destroy ( e );
}
// When done with the watcher, it needs to be destroyed to release memory:
kvWatcher_Destroy ( w );
키 기록을 얻으려면:
kvEntryList l ;
int i ;
// The list is defined on the stack and will be initilized/updated by this call:
s = kvStore_History ( & l , kv , "MY_KEY" , NULL );
for ( i = 0 ; i < l . Count ; i ++ )
{
kvEntry * e = l . Entries [ i ];
// Do something with the entry...
}
// When done with the list, call this to free entries and the content of the list.
kvEntryList_Destroy ( & l );
// In order to set a timeout to get the history, we need to do so through options:
kvWatchOptions o ;
kvWatchOptions_Init ( & o );
o . Timeout = 5000 ; // 5 seconds.
s = kvStore_History ( & l , kv , "MY_KEY" , & o );
버킷의 키를 얻는 방법은 다음과 같습니다.
kvKeysList l ;
int i ;
// If no option is required, pass NULL as the last argument.
s = kvStore_Keys ( & l , kv , NULL );
// Check error..
// Go over all keys:
for ( i = 0 ; i < l . Count ; i ++ )
printf ( "Key: %sn" , l . Keys [ i ]);
// When done, list need to be destroyed.
kvKeysList_Destroy ( & l );
// If option need to be specified:
kvWatchOptions o ;
kvWatchOptions_Init ( & o );
o . Timeout = 5000 ; // 5 seconds.
s = kvStore_Keys ( & l , kv , & o );
헤더는 버전 2.2.0+의 서버에 연결할 때 사용할 수 있습니다.
이는 http 헤더와 매우 유사합니다. 이는 키/값 쌍의 맵이며 값은 문자열 배열입니다.
헤더를 사용하면 사용자는 메시지 페이로드를 방해하지 않고 메시지에 대한 메타 정보를 추가할 수 있습니다.
애플리케이션이 헤더를 이해하지 못하는 서버에 연결되어 있을 때 헤더가 포함된 메시지를 보내려고 하면 게시 호출이 NATS_NO_SERVER_SUPPORT
오류를 반환합니다.
현재 연결된 서버가 헤더를 지원하는지 확인하는 API가 있습니다.
natsStatus s = natsConnection_HasHeaderSupport ( conn );
if ( s == NATS_NO_SERVER_SUPPORT )
// deal with server not supporting this feature.
서버가 헤더를 이해하지만 이해하지 못하는 클라이언트에 메시지를 전달하려고 하는 경우 이전 클라이언트가 계속 메시지를 받을 수 있도록 헤더가 제거됩니다. 애플리케이션이 헤더에 의존하는 경우 모든 클라이언트와 서버를 헤더를 지원하는 버전으로 유지하는 것이 중요합니다.
헤더 API에 대한 자세한 내용을 보려면 examples/getstarted/headers.c
참조하세요.
*
와일드카드는 주제의 모든 수준에서 모든 토큰과 일치합니다.
natsConnection_Subscribe ( & sub , nc , "foo.*.baz" , onMsg , NULL );
이 구독자는 다음 주소로 전송된 메시지를 받습니다.
그러나 다음 메시지는 수신되지 않습니다.
>
와일드카드는 제목의 실패 길이와 일치하며 마지막 토큰만 될 수 있습니다.
natsConnection_Subscribe ( & sub , nc , "foo.>" , onMsg , NULL );
이 구독자는 다음 주소로 전송된 모든 메시지를 받습니다.
그러나 다음 날짜에 전송된 메시지는 수신되지 않습니다.
이 주제에 대해 게시하면 위의 두 구독자가 다음 메시지를 받게 됩니다.
natsConnection_PublishString ( nc , "foo.bar.baz" , "got it?" );
동일한 대기열 이름을 가진 모든 구독은 대기열 그룹을 형성합니다. 각 메시지는 대기열 의미론을 사용하여 대기열 그룹당 한 명의 구독자에게만 전달됩니다. 원하는 만큼 대기열 그룹을 가질 수 있습니다. 일반 가입자는 예상대로 계속 작동합니다.
natsConnection_QueueSubscribe ( & sub , nc , "foo" , "job_workers" , onMsg , NULL );
(이러한 API가 작동하려면 기본적으로 TLS 지원을 사용하여 라이브러리를 구축해야 합니다. 자세한 내용은 TLS를 사용하거나 사용하지 않고 빌드하는 방법에 대한 빌드 장을 참조하세요.)
SSL/TLS 연결은 natsOptions
를 사용하여 구성됩니다. 원하는 보안 수준에 따라 natsOptions_SetSecure()
호출에서 secure boolean을 true로 설정하는 것만큼 간단할 수 있습니다.
전체 보안(클라이언트가 서버 인증서를 확인하고 서버가 클라이언트 인증서를 요구함)을 사용하더라도 설정에는 몇 번의 호출만 필요합니다.
// Here is the minimum to create a TLS/SSL connection:
// Create an options object.
natsOptions_Create ( & opts );
// Set the secure flag.
natsOptions_SetSecure ( opts , true);
// You may not need this, but suppose that the server certificate
// is self-signed and you would normally provide the root CA, but
// don't want to. You can disable the server certificate verification
// like this:
natsOptions_SkipServerVerification ( opts , true);
// Connect now...
natsConnection_Connect ( & nc , opts );
// That's it! On success you will have a secure connection with the server!
(...)
// This example shows what it takes to have a full SSL configuration,
// including server expected's hostname, root CA, client certificates
// and specific ciphers to use.
// Create an options object.
natsOptions_Create ( & opts );
// Set the secure flag.
natsOptions_SetSecure ( opts , true);
// For a server with a trusted chain built into the client host,
// simply designate the server name that is expected. Without this
// call, the server certificate is still verified, but not the
// hostname.
natsOptions_SetExpectedHostname ( opts , "localhost" );
// Instead, if you are using a self-signed cert and need to load in the CA.
natsOptions_LoadCATrustedCertificates ( opts , caCertFileName );
// If the server requires client certificates, provide them along with the
// private key, all in one call.
natsOptions_LoadCertificatesChain ( opts , certChainFileName , privateKeyFileName );
// You can also specify preferred ciphers if you want.
natsOptions_SetCiphers ( opts , "-ALL:HIGH" );
// Then simply pass the options object to the connect call:
natsConnection_Connect ( & nc , opts );
// That's it! On success you will have a secure connection with the server!