1
0
mirror of https://github.com/taigrr/nats.docs synced 2025-01-18 04:03:23 -08:00

Merge pull request #145 from nats-io/add_c_examples

Add C Client examples
This commit is contained in:
Ginger Collison 2020-08-26 09:35:41 -05:00 committed by GitHub
commit 50c1597726
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1165 additions and 0 deletions

View File

@ -110,5 +110,26 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
const char *servers[] = {"nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"};
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetServers(opts, servers, 3);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -85,5 +85,26 @@ let nc = await connect({
});
```
{% endtab %}
{% tab title="C" %}
```c
nnatsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
// Set the timeout to 10 seconds (10,000 milliseconds)
s = natsOptions_SetTimeout(opts, 10000);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -85,5 +85,19 @@ connect()
// add a .catch/.finally
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsStatus s;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
if (s != NATS_OK)
// handle error
// Destroy connection, no-op if conn is NULL.
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -89,6 +89,25 @@ nc.on('connect', (nc: Client, url: string, options: ServerInfo) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
if (s == NATS_OK)
{
int64_t mp = natsConnection_GetMaxPayload(conn);
printf("Max payload: %d\n", (int) mp);
}
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
## Turn On Pedantic Mode
@ -178,6 +197,26 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetPedantic(opts, true);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
## Set the Maximum Control Line Size
@ -236,6 +275,12 @@ let nc = NATS.connect({
// control line size is not configurable on TypeScript NATS client.
```
{% endtab %}
{% tab title="C" %}
```c
// control line is not configurable on C NATS client.
```
{% endtab %}
{% endtabs %}
## Turn On/Off Verbose Mode
@ -325,5 +370,25 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetVerbose(opts, true);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -86,5 +86,25 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetName(opts, "API Name Option Example");
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -84,5 +84,25 @@ let nc = await connect({
url: "nats://demo.nats.io:4222", noEcho: true});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetNoEcho(opts, true);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -93,5 +93,29 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
// Set Ping interval to 20 seconds (20,000 milliseconds)
s = natsOptions_SetPingInterval(opts, 20000);
if (s == NATS_OK)
// Set the limit to 5
s = natsOptions_SetMaxPingsOut(opts, 5);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -82,5 +82,23 @@ end
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsStatus s;
// If connecting to the default port, the URL can be simplified
// to just the hostname/IP.
// That is, the connect below is equivalent to:
// natsConnection_ConnectTo(&conn, "nats://demo.nats.io:4222");
s = natsConnection_ConnectTo(&conn, "demo.nats.io");
if (s != NATS_OK)
// handle error
// Destroy connection, no-op if conn is NULL.
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -168,6 +168,53 @@ nc.on('reconnect', (nc, url) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
static void
disconnectedCB(natsConnection *conn, void *closure)
{
// Do something
printf("Connection disconnected\n");
}
static void
reconnectedCB(natsConnection *conn, void *closure)
{
// Do something
printf("Connection reconnected\n");
}
static void
closedCB(natsConnection *conn, void *closure)
{
// Do something
printf("Connection closed\n");
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetDisconnectedCB(opts, disconnectedCB, NULL);
if (s == NATS_OK)
s = natsOptions_SetReconnectedCB(opts, reconnectedCB, NULL);
if (s == NATS_OK)
s = natsOptions_SetClosedCB(opts, closedCB, NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
## Listen for New Servers
@ -254,6 +301,52 @@ nc.on('serversChanged', (ce) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
static void
discoveredServersCB(natsConnection *conn, void *closure)
{
natsStatus s = NATS_OK;
char **servers = NULL;
int count = 0;
s = natsConnection_GetDiscoveredServers(conn, &servers, &count);
if (s == NATS_OK)
{
int i;
// Do something...
for (i=0; i<count; i++)
printf("Discovered server: %s\n", servers[i]);
// Free allocated memory
for (i=0; i<count; i++)
free(servers[i]);
free(servers);
}
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetDiscoveredServersCB(opts, discoveredServersCB, NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
## Listen for Errors
@ -367,5 +460,34 @@ nc.on('error', (err) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
static void
errorCB(natsConnection *conn, natsSubscription *sub, natsStatus s, void *closure)
{
// Do something
printf("Error: %d - %s\n", s, natsStatus_GetText(s));
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetErrorHandler(opts, errorCB, NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -110,6 +110,40 @@ await nc.subscribe("updates", cb=cb, pending_bytes_limit=5*1024*1024, pending_ms
// slow pending limits are not configurable on TypeScript NATS client.
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsSubscription *sub1 = NULL;
natsSubscription *sub2 = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Subscribe
if (s == NATS_OK)
s = natsConnection_Subscribe(&sub1, conn, "updates", onMsg, NULL);
// Set limits of 1000 messages or 5MB, whichever comes first
if (s == NATS_OK)
s = natsSubscription_SetPendingLimits(sub1, 1000, 5*1024*1024);
// Subscribe
if (s == NATS_OK)
s = natsConnection_Subscribe(&sub2, conn, "updates", onMsg, NULL);
// Set no limits for this subscription
if (s == NATS_OK)
s = natsSubscription_SetPendingLimits(sub2, -1, -1);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub1);
natsSubscription_Destroy(sub2);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
## Detect a Slow Consumer and Check for Dropped Messages
@ -232,5 +266,35 @@ public class SlowConsumerListener {
// slow consumer detection is not configurable on NATS TypeScript client.
```
{% endtab %}
{% tab title="C" %}
```c
static void
errorCB(natsConnection *conn, natsSubscription *sub, natsStatus s, void *closure)
{
// Do something
printf("Error: %d - %s", s, natsStatus_GetText(s));
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetErrorHandler(opts, errorCB, NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -114,5 +114,44 @@ nc.subscribe("updates", (err, msg) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
static void
onMsg(natsConnection *conn, natsSubscription *sub, natsMsg *msg, void *closure)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Need to destroy the message!
natsMsg_Destroy(msg);
}
(...)
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsStatus s;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
if (s == NATS_OK)
{
// Creates an asynchronous subscription on subject "foo".
// When a message is sent on subject "foo", the callback
// onMsg() will be invoked by the client library.
// You can pass a closure as the last argument.
s = natsConnection_Subscribe(&sub, conn, "foo", onMsg, NULL);
}
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -202,6 +202,73 @@ await nc.drain();
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
static void
onMsg(natsConnection *conn, natsSubscription *sub, natsMsg *msg, void *closure)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Add some delay while processing
nats_Sleep(200);
// Need to destroy the message!
natsMsg_Destroy(msg);
}
static void
closeHandler(natsConnection *conn, void *closure)
{
cond_variable cv = (cond_variable) closure;
notify_cond_variable(cv);
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsSubscription *sub = NULL;
natsStatus s = NATS_OK;
cond_variable cv = new_cond_variable(); // some fictuous way to notify between threads.
s = natsOptions_Create(&opts);
if (s == NATS_OK)
// Setup a close handler and pass a reference to our condition variable.
s = natsOptions_SetClosedCB(opts, closeHandler, (void*) cv);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
// Subscribe
if (s == NATS_OK)
s = natsConnection_Subscribe(&sub, conn, "foo", onMsg, NULL);
// Publish a message
if (s == NATS_OK)
s = natsConnection_PublishString(conn, "foo", "hello");
// Drain the connection, which will close it when done.
if (s == NATS_OK)
s = natsConnection_Drain(conn);
// Wait for the connection to be closed
if (s == NATS_OK)
cond_variable_wait(cv);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
The mechanics of drain for a subscription are simpler:
@ -366,6 +433,41 @@ let sub = await nc.subscribe('updates', (err, msg) => {
}, {queue: "workers"});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Subscribe
if (s == NATS_OK)
s = natsConnection_Subscribe(&sub, conn, "foo", onMsg, NULL);
// Publish 2 messages
if (s == NATS_OK)
{
int i;
for (i=0; (s == NATS_OK) && (i<2); i++)
{
s = natsConnection_PublishString(conn, "foo", "hello");
}
}
// Call Drain on the subscription. It unsubscribes but
// wait for all pending messages to be processed.
if (s == NATS_OK)
s = natsSubscription_Drain(sub);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
Because draining can involve messages flowing to the server, for a flush and asynchronous message processing, the timeout for drain should generally be higher than the timeout for a simple message request/reply or similar.

View File

@ -119,6 +119,42 @@ await nc.subscribe('updates', (err, msg) => {
}, {queue: "workers"});
```
{% endtab %}
{% tab title="C" %}
```c
static void
onMsg(natsConnection *conn, natsSubscription *sub, natsMsg *msg, void *closure)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Need to destroy the message!
natsMsg_Destroy(msg);
}
(...)
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsStatus s;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Create a queue subscription on "updates" with queue name "workers"
if (s == NATS_OK)
s = natsConnection_QueueSubscribe(&sub, conn, "updates", "workers", onMsg, NULL);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
If you run this example with the publish examples that send to `updates`, you will see that one of the instances gets a message while the others you run won't. But the instance that receives the message will change.

View File

@ -134,5 +134,43 @@ await nc.subscribe('time', (err, msg) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsMsg *msg = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Subscribe
if (s == NATS_OK)
s = natsConnection_SubscribeSync(&sub, conn, "time");
// Wait for messages
if (s == NATS_OK)
s = natsSubscription_NextMsg(&msg, sub, 10000);
if (s == NATS_OK)
{
char buf[64];
snprintf(buf, sizeof(buf), "%lld", nats_Now());
// Send the time as a response
s = natsConnection_Publish(conn, natsMsg_GetReply(msg), buf, (int) strlen(buf));
// Destroy message that was received
natsMsg_Destroy(msg);
}
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -168,5 +168,11 @@ nc.subscribe('updates', (err, msg) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
// Structured data is not configurable in C NATS Client.
```
{% endtab %}
{% endtabs %}

View File

@ -71,5 +71,41 @@ nc.close();
/ Typescript NATS subscriptions are always async.
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsMsg *msg = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Subscribe
if (s == NATS_OK)
s = natsConnection_SubscribeSync(&sub, conn, "updates");
// Wait for messages
if (s == NATS_OK)
s = natsSubscription_NextMsg(&msg, sub, 10000);
if (s == NATS_OK)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Destroy message that was received
natsMsg_Destroy(msg);
}
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -143,5 +143,45 @@ let sub2 = await nc.subscribe(createInbox(), (err, msg) => {
sub2.unsubscribe(10);
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsMsg *msg = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Subscribe
if (s == NATS_OK)
s = natsConnection_SubscribeSync(&sub, conn, "updates");
// Unsubscribe after 1 message is received
if (s == NATS_OK)
s = natsSubscription_AutoUnsubscribe(sub, 1);
// Wait for messages
if (s == NATS_OK)
s = natsSubscription_NextMsg(&msg, sub, 10000);
if (s == NATS_OK)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Destroy message that was received
natsMsg_Destroy(msg);
}
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -140,5 +140,29 @@ let sub = await nc.subscribe(createInbox(), (err, msg) => {
sub.unsubscribe();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Subscribe
if (s == NATS_OK)
s = natsConnection_SubscribeSync(&sub, conn, "updates");
// Unsubscribe
if (s == NATS_OK)
s = natsSubscription_Unsubscribe(sub);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -165,6 +165,40 @@ await nc.subscribe('time.us.*', (err, msg) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
static void
onMsg(natsConnection *conn, natsSubscription *sub, natsMsg *msg, void *closure)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Need to destroy the message!
natsMsg_Destroy(msg);
}
(...)
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsStatus s;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
if (s == NATS_OK)
s = natsConnection_Subscribe(&sub, conn, "time.*.east", onMsg, NULL);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
or do something similar with `>`:
@ -335,6 +369,40 @@ await nc.subscribe('time.>', (err, msg) => {
});
```
{% endtab %}
{% tab title="C" %}
```c
static void
onMsg(natsConnection *conn, natsSubscription *sub, natsMsg *msg, void *closure)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Need to destroy the message!
natsMsg_Destroy(msg);
}
(...)
natsConnection *conn = NULL;
natsSubscription *sub = NULL;
natsStatus s;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
if (s == NATS_OK)
s = natsConnection_Subscribe(&sub, conn, "time.>", onMsg, NULL);
(...)
// Destroy objects that were created
natsSubscription_Destroy(sub);
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
The following example can be used to test these two subscribers. The `*` subscriber should receive at most 2 messages, while the `>` subscriber receives 4. More importantly the `time.*.east` subscriber won't receive on `time.us.east.atlanta` because that won't match.

View File

@ -59,6 +59,27 @@ nc.close();
// Reconnect buffer size is not configurable on NATS Typescript client
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
// Set reconnect buffer size in bytes (5 MB)
s = natsOptions_SetReconnectBufSize(opts, 5*1024*1024);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
> _As mentioned throughout this document, each client library may behave slightly differently. Please check the documentation for the library you are using._

View File

@ -80,5 +80,25 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetAllowReconnect(opts, false);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -112,5 +112,46 @@ nc.on('reconnect', (conn, server) => {
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
static void
disconnectedCB(natsConnection *conn, void *closure)
{
// Handle disconnect error event
}
static void
reconnectedCB(natsConnection *conn, void *closure)
{
// Handle reconnect event
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
// Connection event handlers are invoked asynchronously
// and the state of the connection may have changed when
// the callback is invoked.
if (s == NATS_OK)
s = natsOptions_SetDisconnectedCB(opts, disconnectedCB, NULL);
if (s == NATS_OK)
s = natsOptions_SetReconnectedCB(opts, reconnectedCB, NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -75,5 +75,25 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetMaxReconnect(opts, 10);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -90,5 +90,27 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
const char *servers[] = {"nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"};
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetServers(opts, servers, 3);
if (s == NATS_OK)
s = natsOptions_SetNoRandomize(opts, true);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -76,5 +76,26 @@ let nc = await connect({
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
// Set reconnect interval to 10 seconds (10,000 milliseconds)
s = natsOptions_SetReconnectWait(opts, 10000);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -88,5 +88,28 @@ let nc = await connect({
});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
// Pass the credential file this way if the file contains both user JWT and seed.
// Otherwise, if the content is split, the first file is the user JWT, the second
// contains the seed.
s = natsOptions_SetUserCredentialsFromFiles(opts, "path_to_creds_file", NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -105,5 +105,45 @@ let nc = await connect({
});
```
{% endtab %}
{% tab title="C" %}
```c
static natsStatus
sigHandler(
char **customErrTxt,
unsigned char **signature,
int *signatureLength,
const char *nonce,
void *closure)
{
// Sign the given `nonce` and return the signature as `signature`.
// This needs to allocate memory. The length of the signature is
// returned as `signatureLength`.
// If an error occurs the user can return specific error text through
// `customErrTxt`. The library will free this pointer.
return NATS_OK;
}
(...)
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
const char *pubKey = "my public key......";
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetNKey(opts, pubKey, sigHandler, NULL);
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -203,6 +203,28 @@ let nc = await connect({
});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetCertificatesChain(opts, "client-cert.pem", "client-key.pem");
if (s == NATS_OK)
s = natsOptions_SetCATrustedCertificates(opts, "rootCA.pem");
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
## Connecting with the TLS Protocol

View File

@ -69,6 +69,26 @@ end
let nc = await connect({url: server.nats, token: "mytoken"});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetToken(opts, "mytoken");
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
## Connecting with a Token in the URL
@ -134,5 +154,25 @@ let url = `nats://:mytoken@127.0.0.1:${port}`;
let nc = await connect({url: url});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetURL(opts, "nats://mytoken@127.0.0.1:4222");
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -93,6 +93,26 @@ end
let nc = await connect({url: server.nats, user: "myname", pass: "password"});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetUserInfo(opts, "myname", "password");
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}
## Connecting with a User/Password in the URL
@ -172,5 +192,25 @@ let url = `nats://myname:password@127.0.0.1:${port}`;
let nc = await connect({url: url});
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsOptions *opts = NULL;
natsStatus s = NATS_OK;
s = natsOptions_Create(&opts);
if (s == NATS_OK)
s = natsOptions_SetURL(opts, "nats://myname:password@127.0.0.1:4222");
if (s == NATS_OK)
s = natsConnection_Connect(&conn, opts);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
natsOptions_Destroy(opts);
```
{% endtab %}
{% endtabs %}

View File

@ -109,6 +109,29 @@ await nc.flush();
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Send a request and wait for up to 1 second
if (s == NATS_OK)
s = natsConnection_PublishString(conn, "foo", "All is Well");
// Sends a PING and wait for a PONG from the server, up to the given timeout.
// This gives guarantee that the server has processed the above message.
if (s == NATS_OK)
s = natsConnection_FlushTimeout(conn, 1000);
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
## Flush and Ping/Pong

View File

@ -155,5 +155,23 @@ await nc.subscribe(inbox, (err, msg) => {
nc.publish('time', "", inbox);
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Publish a message and provide a reply subject
if (s == NATS_OK)
s = natsConnection_PublishRequestString(conn, "request", "reply", "this is the request");
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}

View File

@ -110,6 +110,36 @@ t.log('the time is', msg.data);
nc.close();
```
{% endtab %}
{% tab title="C" %}
```c
natsConnection *conn = NULL;
natsMsg *msg = NULL;
natsStatus s = NATS_OK;
s = natsConnection_ConnectTo(&conn, NATS_DEFAULT_URL);
// Send a request and wait for up to 1 second
if (s == NATS_OK)
s = natsConnection_RequestString(&msg, conn, "request", "this is the request", 1000);
if (s == NATS_OK)
{
printf("Received msg: %s - %.*s\n",
natsMsg_GetSubject(msg),
natsMsg_GetDataLength(msg),
natsMsg_GetData(msg));
// Destroy the message that was received
natsMsg_Destroy(msg);
}
(...)
// Destroy objects that were created
natsConnection_Destroy(conn);
```
{% endtab %}
{% endtabs %}
You can think of request-reply in the library as a subscribe, get one message, unsubscribe pattern. In Go this might look something like:

View File

@ -106,5 +106,11 @@ let nc = await connect({
nc.publish('updates', {ticker: 'GOOG', price: 1200});
```
{% endtab %}
{% tab title="C" %}
```c
// Structured data is not configurable in C NATS Client.
```
{% endtab %}
{% endtabs %}