Client AC pour la messagerie NATS.
Allez ici pour la documentation en ligne et consultez les questions fréquemment posées.
Cette implémentation du client NATS est fortement basée sur le client NATS GO. Il existe un support pour Mac OS/X, Linux et Windows (bien que nous n'ayons pas de matrice de support de plate-forme spécifique).
Il existe plusieurs gestionnaires de packages avec la bibliothèque client NATS C disponibles. Si vous en connaissez un qui ne figure pas dans cette liste, veuillez soumettre un PR pour l'ajouter !
Tout d'abord, téléchargez le code source :
git clone [email protected]:nats-io/nats.c.git .
Pour créer la bibliothèque, utilisez CMake. Notez que par défaut, l'API NATS Streaming sera construite et incluse dans la bibliothèque NATS. Voir ci-dessous si vous ne souhaitez pas créer les API liées au streaming.
Assurez-vous que CMake est ajouté à votre chemin. Si vous construisez sous Windows, ouvrez un shell de commande dans le menu Visual Studio Tools et sélectionnez le shell de commande approprié (x64 ou x86 pour les versions 64 ou 32 bits respectivement). Vous devrez probablement également l'exécuter avec des privilèges d'administrateur.
Créez un répertoire build
(n'importe quel nom fonctionnerait) à partir de l'arborescence source racine et cd
-y. Ensuite, lancez cette commande pour la première fois :
cmake ..
Dans certaines architectures, vous pouvez rencontrer une erreur de compilation pour mutex.co
car il n'y a pas de support pour l'instruction assembleur que nous utilisons pour céder lors de la rotation en essayant d'acquérir un verrou.
Vous pouvez obtenir ce type d'erreur de construction :
/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
Si tel est le cas, vous pouvez résoudre ce problème en activant l'indicateur NATS_BUILD_NO_SPIN
(ou en utilisant -DNATS_NO_SPIN
si vous compilez sans CMake) :
cmake .. -DNATS_BUILD_NO_SPIN=ON
Si vous aviez déjà construit la bibliothèque, vous devrez peut-être effectuer un make clean
, ou simplement supprimer et recréer le répertoire build avant d'exécuter la commande cmake.
Pour construire sous Windows, vous devez sélectionner le générateur de build. Par exemple, pour sélectionner nmake
, vous exécuterez :
cmake .. -G "NMake Makefiles"
Exécuter cmake -h
vous donnerait la liste des options possibles et tous les noms du générateur.
Alternativement, vous pouvez exécuter la version GUI. À partir de ce même shell de commande de build , démarrez l'interface graphique :
c:program files (x86)CMakebincmake-gui.exe
Si vous avez commencé avec un répertoire de build vide, vous devrez sélectionner la source et le répertoire de build, puis cliquer sur Configure
. Ici, vous pourrez sélectionner dans la liste déroulante le nom du générateur de build. Une fois terminé, cliquez sur Generate
. Ensuite, vous pouvez revenir à votre shell de commande ou à Visual Studio et créer.
Pour modifier certaines options de construction, vous devez modifier le cache et le reconstruire.
make edit_cache
Notez que si vous construisez sous Windows et avez sélectionné "NMake Makefiles", remplacez toutes les références suivantes à make
par nmake
.
La modification du cache vous permet de sélectionner le type de build (Debug, Release, etc.), l'architecture (64 ou 32 bits), etc.
La cible par défaut construira tout, c'est-à-dire les bibliothèques NATS statiques et partagées ainsi que les exemples et le programme de test. Chacun se trouve dans son répertoire respectif sous votre répertoire de build : src
, examples
et test
.
make install
Copiera à la fois les bibliothèques statiques et partagées dans le dossier install/lib
et les en-têtes publics dans install/include
.
Par défaut, la bibliothèque est construite avec le support TLS. Vous pouvez désactiver cela à partir de l'interface graphique de cmake make edit_cache
et basculer l'option NATS_BUILD_WITH_TLS
sur OFF
, ou transmettre l'option directement à la commande cmake
:
cmake .. -DNATS_BUILD_WITH_TLS=OFF
À partir de 2.0.0
, lors de la construction avec la prise en charge TLS/SSL, le nom d'hôte attendu du certificat de serveur est toujours vérifié. Cela signifie que le nom d'hôte fourni dans la ou les URL ou via l'option natsOptions_SetExpectedHostname()
sera utilisé pour vérifier le nom d'hôte présent dans le certificat. Avant 2.0.0
, le nom d'hôte n'était vérifié que si l'option natsOptions_SetExpectedHostname()
était invoquée.
Bien que nous vous recommandons de conserver le nouveau comportement par défaut, vous pouvez restaurer le comportement précédent en créant la bibliothèque en désactivant cette option :
cmake .. -DNATS_BUILD_TLS_FORCE_HOST_VERIFY=OFF
Le client NATS C est construit à l'aide des API de la bibliothèque OpenSSL. Par défaut, nous utilisons les API 3.0+
. Étant donné qu'OpenSSL 1.0.2
n'est plus pris en charge, à partir de la version NATS C Client v3.6.0
, la variable CMake NATS_BUILD_TLS_USE_OPENSSL_1_1_API
est désormais définie sur ON
par défaut (si vous configurez un nouvel environnement) et utilisera les API OpenSSL de 1.1+
/ API 3.0+
. Vous pourrez toujours compiler avec la bibliothèque OpenSSL 1.0.2
en définissant cette option CMake sur OFF
:
cmake .. -DNATS_BUILD_TLS_USE_OPENSSL_1_1_API=OFF
La variable NATS_BUILD_TLS_USE_OPENSSL_1_1_API
est obsolète, ce qui signifie qu'à l'avenir, cette option sera simplement supprimée et seules les API OpenSSL 3.0+
seront utilisées. Le code de la bibliothèque utilisant les anciennes API OpenSSL sera également supprimé.
Notez que la variable NATS_BUILD_WITH_TLS_CLIENT_METHOD
qui était obsolète dans v2.0.0
a désormais été supprimée.
Étant donné que le client NATS C est lié dynamiquement à la bibliothèque OpenSSL, vous devez vous assurer que vous exécutez ensuite votre application sur une bibliothèque OpenSSL 1.1+/3.0+.
Si vous souhaitez créer un lien vers la bibliothèque statique OpenSSL, vous devez supprimer le CMakeCache.txt
et le régénérer avec l'option supplémentaire :
rm CMakeCache.txt
cmake .. -DNATS_BUILD_OPENSSL_STATIC_LIBS=ON
Appelez ensuite make
(ou équivalent en fonction de votre plate-forme) et cela devrait garantir que la bibliothèque (et les exemples et/ou l'exécutable de la suite de tests) sont liés à la bibliothèque OpenSSL, si elle a été trouvée par CMake.
Lors de la création de la bibliothèque avec la prise en charge du streaming, la bibliothèque NATS utilise la bibliothèque libprotobuf-c. Lorsque cmake s'exécute pour la première fois (ou après avoir supprimé CMakeCache.txt
et appelé à nouveau cmake ..
), il recherche la bibliothèque libprotobuf-c. S'il ne le trouve pas, un message est imprimé et le processus de construction échoue. CMake recherche la bibliothèque dans les répertoires où se trouvent habituellement les bibliothèques. Cependant, si vous souhaitez spécifier un répertoire spécifique où se trouve la bibliothèque, vous devez procéder comme suit :
cmake .. -DNATS_PROTOBUF_DIR=
La bibliothèque statique sera utilisée par défaut. Si vous souhaitez changer cela, ou si la bibliothèque n'a pas le nom attendu, vous devez procéder comme suit :
# Use the library named mylibproto.so located at /my/location
cmake .. -DNATS_PROTOBUF_LIBRARY=/my/location/mylibproto.so
Les deux pourraient être combinés si l'en-tête d'inclusion se trouve dans un répertoire différent
# 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
Si vous ne souhaitez pas créer les API NATS Streaming à inclure dans la bibliothèque NATS :
cmake .. -DNATS_BUILD_STREAMING=OFF
Lors de l'utilisation des nouvelles fonctionnalités de sécurité NATS 2.0, la bibliothèque doit signer certains "nonce" envoyés par le serveur lors d'une connexion ou d'une reconnexion. Nous utilisons la signature à clé publique Ed25519. La bibliothèque est livrée avec du code pour effectuer la signature. Dans la plupart des cas, tout ira bien, mais si les performances sont un problème (surtout si vous prévoyez d'utiliser beaucoup la fonction natsConnection_Sign()
), vous aurez la possibilité de construire avec la bibliothèque Libsodium.
Suivez les instructions pour installer la bibliothèque libsodium ici.
Sur macOS, vous pouvez utiliser brew
:
brew install libsodium
Sous Linux, vous pouvez utiliser apt-get
apt-get install libsodium-dev
Une fois installé, vous pouvez reconstruire le client NATS C en activant d'abord l'utilisation de la bibliothèque libsodium :
cmake .. -DNATS_BUILD_USE_SODIUM=ON
Si la bibliothèque libsodium est installée dans un emplacement non standard que CMake ne peut pas trouver, vous pouvez spécifier l'emplacement de ce répertoire :
cmake .. -DNATS_BUILD_USE_SODIUM=ON -DNATS_SODIUM_DIR=/my/path/to/libsodium
Sur les plateformes où valgrind
est disponible, vous pouvez exécuter les tests avec des vérifications de mémoire. Voici un exemple :
make test ARGS="-T memcheck"
Ou bien, vous pouvez appeler directement le programme ctest
:
ctest -T memcheck -V -I 1,4
La commande ci-dessus exécuterait les tests avec valgrind
( -T memcheck
), avec une sortie détaillée ( -V
), et exécuterait les tests de 1 à 4 ( -I 1,4
).
Si vous ajoutez un test à test/test.c
, vous devez l'ajouter dans le fichier list_test.txt
. Chaque entrée contient juste le nom du test, la fonction doit être nommée à l'identique, avec un préfixe test_
. La liste est classée par ordre alphabétique, mais ce n’est pas obligatoire, vous pouvez l’ajouter n’importe où.
Si vous ajoutez un benchmark, il doit être ajouté au list_bench.txt
. Ces tests sont étiquetés différemment ( -L 'bench'
) et exécutés séparément sur CI.
Vous devez réexécuter cmake
pour que les modifications prennent effet :
cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ivan/nats.c/build
Vous pouvez utiliser les variables d'environnement suivantes pour influencer le comportement de la suite de tests.
Lors de l'exécution avec vérification de la mémoire, le timing change et les performances globales sont plus lentes. La variable suivante permet à la suite de tests d'ajuster certaines valeurs utilisées lors du test :
export NATS_TEST_VALGRIND=yes
Sous Windows, il serait set
à la place de export
.
Lors de l'exécution des tests en mode détaillé, la variable d'environnement suivante vous permet de voir la sortie du serveur depuis le test lui-même. Sans cette option, la sortie du serveur est réduite au silence :
export NATS_TEST_KEEP_SERVER_OUTPUT=yes
Si vous souhaitez modifier le nom de l'exécutable du serveur par défaut ( nats-server.exe
) ou spécifier un emplacement spécifique, utilisez cette variable d'environnement :
set NATS_TEST_SERVER_EXE=c:testnats-server.exe
L'API publique a été documentée à l'aide de Doxygen.
Pour générer la documentation, allez dans le répertoire doc
et tapez la commande suivante :
doxygen DoxyFile.NATS.Client
Si vous basculez la construction des API Streaming et que la documentation ne correspond plus à ce qui est en cours de construction, vous pouvez mettre à jour la documentation en changeant l'indicateur de construction NATS_UPDATE_DOC
et reconstruire la documentation.
Depuis le répertoire build :
cmake .. -DNATS_UPDATE_DOC=ON
make
cd /doc
doxygen DoxyFile.NATS.Client
La documentation générée sera située dans le répertoire html
. Pour voir la documentation, pointez votre navigateur vers le fichier index.html
dans ce répertoire.
Allez ici pour la documentation en ligne.
Le code source est également assez documenté.
Cette section répertorie les changements importants tels que les avis de dépréciation, etc...
2.0.0
Cette version présente les concepts de sécurité utilisés par NATS Server 2.0.0
et s'aligne donc sur la version du serveur. De nouvelles API ont été introduites, mais le changement le plus important est le nouveau comportement par défaut avec les connexions TLS :
Lors de l'établissement d'une connexion sécurisée, le nom d'hôte du certificat du serveur est désormais toujours vérifié, que l'utilisateur ait ou non invoqué natsOptions_SetExpectedHostname()
. Cela peut interrompre les applications qui utilisaient par exemple une adresse IP pour se connecter à un serveur dont le certificat n'avait que le nom d'hôte. Cela peut être résolu en modifiant votre application pour utiliser le nom d'hôte dans l'URL ou en utilisant natsOptions_SetExpectedHostname()
. Si cela n'est pas possible, vous pouvez restaurer l'ancien comportement en créant la bibliothèque avec le nouveau comportement désactivé. Voir #tls-support pour plus d'informations.
Ce référentiel incluait des bibliothèques précompilées de libprotobuf-c pour macOS, Linux et Windows ainsi que les fichiers d'en-tête (dans le répertoire /pbuf
). Nous avons maintenant supprimé ce répertoire et exigeons que l'utilisateur installe la bibliothèque libprotobuf-c séparément. Consultez les instructions de construction pour spécifier l'emplacement de la bibliothèque si CMake ne peut pas la trouver directement.
1.8.0
natsConnStatus
ont été préfixées par NATS_CONN_STATUS_
. Si votre application n'utilise pas de référencement à une valeur d'origine, telle que CONNECTED
ou CLOSED
, etc., vous n'avez rien à faire. Si vous le faites, vous avez deux options :NATS_BUILD_NO_PREFIX_CONNSTS
. Cela peut être fait de cette façon à partir du répertoire de construction : cmake .. -DNATS_BUILD_NO_PREFIX_CONNSTS=ON
Le répertoire examples/getstarted
contient un ensemble d'exemples simples entièrement fonctionnels, mais très simples. L’objectif est de démontrer à quel point l’API est simple à utiliser.
Un ensemble d’exemples plus complexes se trouve dans le répertoire examples/
et peut également être utilisé pour comparer la bibliothèque cliente.
Notez que par souci de simplicité, la vérification des erreurs n’est pas effectuée ici.
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 );
}
La prise en charge de JetStream commence avec la version v3.0.0
de la bibliothèque et le serveur NATS v2.2.0+
, bien que l'obtention des codes d'erreur spécifiques à JetStream nécessite que le serveur soit à la version v2.3.0+
. Certaines options de configuration ne sont disponibles qu'à partir de v2.3.3
. Nous vous recommandons donc d'utiliser la dernière version du serveur NATS pour bénéficier d'une meilleure expérience.
Consultez les exemples nommés js-xxx.c
dans le répertoire examples
pour obtenir des exemples sur la façon d'utiliser l'API. Les nouveaux objets et API sont entièrement documentés dans la documentation en ligne.
// 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 );
FONCTION EXPÉRIMENTALE ! Nous nous réservons le droit de modifier l'API sans nécessairement modifier la version majeure de la bibliothèque.
Un magasin KeyValue est une vue matérialisée basée sur JetStream. Un compartiment est un flux et les clés sont des sujets au sein de ce flux.
Certaines fonctionnalités nécessitent NATS Server v2.6.2
, nous vous recommandons donc d'utiliser la dernière version de NATS Server pour bénéficier d'une meilleure expérience.
Les nouveaux objets et API sont entièrement documentés dans la documentation en ligne.
Exemple de création d'un magasin 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 );
Ceci montre comment "se lier" à un existant :
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 );
Voici comment supprimer un magasin KeyValue sur le serveur :
jsCtx * js = NULL ;
// Assume we got a JetStream context in `js`...
s = js_DeleteKeyValue ( js , "KVS" );
Voici comment mettre une valeur pour une clé donnée :
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" );
Ce qui précède place une valeur pour une clé donnée, mais si l'on veut plutôt s'assurer que la valeur est placée pour la clé uniquement si elle n'a jamais existé auparavant, on appellerait :
// Same note than before: if "rev" is not needed, pass NULL:
s = kvStore_CreateString ( & rev , kv , "MY_KEY" , "my value" );
On peut mettre à jour une clé si et seulement si la dernière révision du serveur correspond à celle transmise à cette 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 );
Voici comment obtenir une clé :
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 );
Voici comment purger une clé :
kvStore * kv = NULL ;
// Assume we got a kvStore...
s = kvStore_Purge ( kv , "MY_KEY" );
Cela supprimera la clé sur le serveur :
kvStore * kv = NULL ;
// Assume we got a kvStore...
s = kvStore_Delete ( kv , "MY_KEY" );
Pour créer un "watcher" pour une clé donnée :
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 );
Pour obtenir l'historique d'une clé :
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 );
Voici comment obtenir les clés d'un seau :
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 );
Les en-têtes sont disponibles lors de la connexion aux serveurs en version 2.2.0+.
Ils ressemblent beaucoup aux en-têtes http. Il s'agit d'une carte de paires clé/valeur, la valeur étant un tableau de chaînes.
Les en-têtes permettent aux utilisateurs d'ajouter des métainformations sur un message sans interférer avec la charge utile du message.
Notez que si une application tente d'envoyer un message avec un en-tête lorsqu'elle est connectée à un serveur qui ne les comprend pas, l'appel de publication renverra l'erreur NATS_NO_SERVER_SUPPORT
.
Il existe une API pour savoir si le serveur actuellement connecté prend en charge les en-têtes :
natsStatus s = natsConnection_HasHeaderSupport ( conn );
if ( s == NATS_NO_SERVER_SUPPORT )
// deal with server not supporting this feature.
Si le serveur comprend les en-têtes mais est sur le point de transmettre le message à un client qui ne le comprend pas, les en-têtes sont supprimés afin que les clients plus anciens puissent toujours recevoir le message. Il est important que tous les clients et serveurs disposent d'une version prenant en charge les en-têtes si les applications s'appuient sur des en-têtes.
Pour plus de détails sur l'API des en-têtes, veuillez obtenir l'exemple : examples/getstarted/headers.c
.
Le caractère générique *
correspond à n'importe quel jeton, à n'importe quel niveau du sujet :
natsConnection_Subscribe ( & sub , nc , "foo.*.baz" , onMsg , NULL );
Cet abonné recevrait des messages envoyés à :
Il ne recevra cependant pas de messages sur :
Le caractère générique >
correspond à n'importe quelle longueur de l'échec d'un sujet et ne peut être que le dernier jeton.
natsConnection_Subscribe ( & sub , nc , "foo.>" , onMsg , NULL );
Cet abonné recevrait tout message envoyé à :
Cependant, il ne recevra pas les messages envoyés sur :
Publier sur ce sujet ferait en sorte que les deux abonnés ci-dessus reçoivent le message :
natsConnection_PublishString ( nc , "foo.bar.baz" , "got it?" );
Tous les abonnements portant le même nom de file d'attente formeront un groupe de files d'attente. Chaque message sera remis à un seul abonné par groupe de files d'attente, à l'aide de la sématique de file d'attente. Vous pouvez créer autant de groupes de files d'attente que vous le souhaitez. Les abonnés normaux continueront à travailler comme prévu.
natsConnection_QueueSubscribe ( & sub , nc , "foo" , "job_workers" , onMsg , NULL );
(Notez que la bibliothèque doit être construite avec le support TLS - qui est par défaut - pour que ces API fonctionnent. Voir le chapitre Build sur la façon de construire avec ou sans TLS pour plus de détails).
Une connexion SSL/TLS est configurée via l'utilisation de natsOptions
. Selon le niveau de sécurité souhaité, cela peut être aussi simple que de définir le booléen sécurisé sur true lors de l'appel natsOptions_SetSecure()
.
Même avec une sécurité totale (certificat de serveur vérifiant le client et serveur nécessitant des certificats clients), la configuration ne nécessite que quelques appels.
// 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!