Utility Methods API for PubNub C-Core SDK
The methods on this page are utility methods that don't fit into other categories.
Configure proxy to be used from the system
Sets the configuration for the Internet proxy, by reading from the system
configuration.
On some platforms (like Windows), there is some (de-facto) standard way of setting a proxy. On others, there may not be. C-core will try to do the best it can on a given platform.
This function can block for a significant time, if system configuration is to do auto-discovery of the proxy. So, call it only on start, restart, wake-up and similar events.
Preconditions
- Call this after
pubnub_init()
on the context
Method(s)
To Configure proxy to be used from the system
you can use the following method(s) in the C-Core SDK:
Declaration
int pubnub_set_proxy_from_system(pubnub_t *p, enum pubnub_proxy_type protocol);
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
p | pubnub_t* | Yes | The context to set proxy configuration for. |
protocol | enum pubnub_proxy_type | Yes | Proxy protocol to use on @p p context. |
Basic Usage
pubnub_set_proxy_from_system(pbp, pbpproxyHTTP_GET);
Returns
Type | Value | Description |
---|---|---|
int | 0 | OK |
!= 0 | Error, specified protocol not supported or error in getting information from the system. |
Enums
Enum type: pubnub_res
Result codes for Functions and transactions.
Members
PNR_OK
Success. Transaction finished successfully.
PNR_ADDR_RESOLUTION_FAILED
Pubnub host name resolution failed. We failed to get an IP address from the PubNub host name (origin
). Most of the time, this comes down to a DNS error.
PNR_CONNECT_FAILED
Connecting to Pubnub server failed. Most often, this means a network outage, but could be many things. If using SSL/TLS
, it could be some of its errors.
PNR_CONNECTION_TIMEOUT
A time-out happened in the network. Mostly, this is because a network outage happened while being connected to the PubNub server, but could be other things.
PNR_TIMEOUT
Time-out before the request has completed. This is reported for a time-out detected by PubNub client itself, not some reported by others (i.e. the TCP/IP
stack).
PNR_ABORTED
Connection to Pubnub aborted (in most cases, a TCP
reset was received)
PNR_IO_ERROR
Communication error (network or HTTP
response format).
PNR_HTTP_ERROR
HTTP
error. Call pubnub_last_http_code()
to get the error code.
PNR_FORMAT_ERROR
Unexpected input in received JSON
.
PNR_CANCELLED
Request cancelled by user.
PNR_STARTED
Transaction started. Await the outcome.
PNR_IN_PROGRESS
Transaction (already) ongoing. Can't start a new transaction while the old one is in progress.
PNR_RX_BUFF_NOT_EMPTY
Receive buffer (from previous transaction) not read, new subscription not allowed.
PNR_TX_BUFF_TOO_SMALL
The buffer is too small. Increase #PUBNUB_BUF_MAXLEN
.
PNR_INVALID_CHANNEL
Channel specification / name is invalid.
PNR_PUBLISH_FAILED
Publish transaction failed - error returned from Pubnub. To see the reason describing the failure, call pubnub_last_publish_result()
.
PNR_CHANNEL_REGISTRY_ERROR
A transaction related to channel registry failed - error returned from Pubnub. To see the reason describing the failure, get the value for key message
from the response (which is a JSON
object) and value for key status
for the numeric code of the error.
PNR_REPLY_TOO_BIG
Reply is too big to fit in our reply buffer. This same error is reported if the reply buffer is statically or dynamically allocated.
Enum type: pubnub_trans
Type of Pubnub operation/transaction
Members
PBTT_NONE
No transaction at all.
PBTT_SUBSCRIBE
Subscribe operation/transaction.
PBTT_PUBLISH
Publish operation/transaction.
PBTT_LEAVE
Leave channel(s) operation/transaction.
PBTT_TIME
Time (get from Pubnub server) operation/transaction.
PBTT_HISTORY
History V2 (get message history for the channel from Pubnub server) operation/transaction.
PBTT_HERENOW
Here-now (get user_ids of currently present users in channel(s)) operation/transaction.
PBTT_GLOBAL_HERENOW
Here-now (get user_ids of currently present users in channel(s)) operation/transaction.
PBTT_WHERENOW
Where-now (get channels in which an user (identified by user_id) is currently present) operation/transaction.
PBTT_SET_STATE
Set state (for a user (identified by user_id) on channel(s)) operation/transaction.
PBTT_STATE_GET
Get state (for a user (identified by user_id) on channel(s)) operation/transaction.
PBTT_REMOVE_CHANNEL_GROUP
Remove a channel group (from the channel-registry) operation/transaction.
PBTT_REMOVE_CHANNEL_FROM_GROUP
Remove a channel from a channel group (in the channel-registry) operation/transaction.
PBTT_ADD_CHANNEL_TO_GROUP
Add a channel to a channel group (in the channel-registry) operation/transaction.
PBTT_LIST_CHANNEL_GROUP
Get a list of all channels in a channel group (from the channel-registry) operation/transaction.
Free a context, with waiting
Tries pubnub_free()
in a tight loop until either:
- It succeeds.
- Time specified in
@p
millisec elapses.
Essentially, it waits for the context to finish its current transaction and then frees it.
This function is much more useful in the callback interface, especially after a pubnub_cancel()
.
This function is not useful at all in the sync interface if you're using only one thread with the @p
pbp context.
Also, if you want to do some other processing while waiting for the transaction to finish, don't use this function.
Method(s)
int pubnub_free_with_timeout(pubnub_t* pbp, unsigned millisec);
Parameter | Type | Required | Description |
---|---|---|---|
pbp | pubnub_t* | Yes | The Pubnub context which to free. |
millisec | unsigned | Yes | Max time to wait for freeing to succeed, in milliseconds . |
Basic Usage
if (0 != pubnub_free_with_timeout(pbp, 1000)) {
puts("Failed to free the context in due time");
}
Returns
Type | Value | Description |
---|---|---|
int | 0 | pubnub_free() succeeded. |
-1 | Failed to pubnub_free() in @p millisec. |
Generate UUID MD5
The name based algorithms (this - v3 and the other - v5) don't need any other state but the arguments they declare. But, they do need a hash, in this case MD5. For various reasons, a particular hash may not be available on a particular platform.
Method(s)
int pubnub_generate_uuid_v3_name_md5(struct Pubnub_UUID *uuid, struct Pubnub_UUID *nsid, void *name, unsigned namelen)
Parameter | Type | Required | Description |
---|---|---|---|
uuid | struct Pubnub_UUID* | Yes | The place to put the generated UUID to. |
nsid | struct Pubnub_UUID* | Yes | The UUID of the namespace used. We provide a few examples. |
name | void* | Yes | Pointer to the data that defines the name you want to use for UUID generation. |
namelen | unsigned | Yes | The length of the name data. |
Basic Usage
char *name = "abcd";
struct Pubnub_UUID uuid;
struct Pubnub_UUID nsid = { {'x', 'y', 'z', 0} };;
if (0 != pubnub_generate_uuid_v3_name_md5(&uuid, &nsid, name, 4)) {
puts("UUID generation unsuccessful");
}
Returns
Type | Description |
---|---|
int | 0: OK (generated), otherwise: error, algorithm not available. |
Generate UUID Random
The nice property of this random-base algorithm is that it needs no state what-so-ever. A not so nice property is that it needs a random number generator of good quality, and you may not have that on a particular platform.
Method(s)
int pubnub_generate_uuid_v4_random(struct Pubnub_UUID *uuid)
Parameter | Type | Required | Description |
---|---|---|---|
uuid | struct Pubnub_UUID* | Yes | The place to put the generated UUID to. |
Basic Usage
struct Pubnub_UUID uuid;
if (0 == pubnub_generate_uuid_v4_random(&uuid)) {
puts("UUID generation unsuccessful");
}
Returns
Type | Description |
---|---|
int | 0: OK (generated), otherwise: error, random number generator not available. |
Other Examples
Creating a function to subscribe to a channel with a unique name
struct Pubnub_UUID uuid;
char channel_name;
if (0 == pubnub_generate_uuid_v4_random(&uuid)) {
channel_name = pubnub_uuid_to_string(&uuid).uuid;
}
pubnub_t ctx = pubnub_alloc();
if (NULL == ctx) {
puts("Couldn't allocate a Pubnub context");
return -1;
}
pubnub_init(ctx, "demo", "demo");
pubnub_subscribe(ctx, channel_name, NULL);
pbresult = pubnub_await(ctx);
if (pbresult != PNR_OK) {
printf("Failed to subscribe, error %d\n", pbresult);
show all 28 linesCreating a unique Authentication Key for Access Manager on initialization
struct Pubnub_UUID uuid;
char *auth_key;
if (0 == pubnub_generate_uuid_v4_random(&uuid)) {
auth_key = pubnub_uuid_to_string(&uuid).uuid;
pubnub_init(ctx, "demo", "demo");
pubnub_set_auth(ctx, auth_key);
}
Generate UUID Time
This generates an UUID using the v1 algorithm (time-based). This algorithm has some state, but, a lot of it is "node" identifier, which is the MAC address of your Ethernet-ish network interface, and most applications have one. If you don't have a MAC, you can use some other identifier. If it has less than 6 octets, will use what we have, but UUIDs will be of lesser quality. If you don't have an identifier to use, than you can generate a random number. If you don't have a random number generator, you can either give up, or use the pubnub_time()
to obtain a high-resolution time as a pseudo-random number.
Besides that, it has the timestamp, which is a 100ns tick timer that started at midnight 15 October 1582. If you have a clock, just convert it to this format and you're good. Since it requires 64-bit integer support, and that is not always available, we are accepting it as a 8-octet array. If you don't have a clock, but have a timer, you can get time via pubnub_time()
operation and later add the timer ticks to it.
Last but not the least, there is the io_clock_seq
, which is generally used if the UUID generator gets the i_node and i_timestamp itself and also keep the state, which we don't do, for greater portability. We emulate this, by keeping a copy (in volatile memory) of the last time-stamp and seeing if it changes and assuming that node changes at first call, so we require the user to gives a random number for the clock sequence on first call. So, basically, on the first call, put a random value in io_clock_seq
, and later just re-use the same variable, this function will update it as needed. If you don't have random number generator, you can use any pseudo-random number source (say a timer tick or some other event counter) - actually use as many as you have and mix the values (the simplest option is just to XOR the values you have, other is to make a message digest (MD5, SHA-1) of all the values).
While rather complex to use, it is very portable and can be made to work, with effort, on pretty much any platform, without the need to obtain unique identifiers yourself (like you need to do for v3 and v5).
Method(s)
int pubnub_generate_uuid_v1_time(struct Pubnub_UUID *o_uuid, uint16_t *io_clock_seq, uint8_t const i_timestamp[8], uint8_t const i_node[6]);
Parameter | Type | Required | Description |
---|---|---|---|
o_uuid | struct Pubnub_UUID* | Yes | The place to put the generated UUID to. |
io_clock_seq | uint16_t* | Yes | Clock Sequence - initialize to a random value on first call, later just reuse. |
i_timestamp | uint8_t const[8] | Yes | Count of 100- nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian reform to the Christian calendar). |
i_node | uint8_t const[6] | Yes | A 6-octet "node" identity. Designed to be an IEEE 802 MAC address, but if you don't have it on your system, you can use something else. |
Basic Usage
struct Pubnub_UUID uuid;
uint16_t clock_seq = 4443; /* some random value */
uint8_t timestamp[8]; /* get a time stamp somehow */
uint8_t node[6] = { 0x5F, 0x82, 0x11, 0x58, 0x02, 0x61 }; /* This is some example MAC address, put your own */
if (0 != pubnub_generate_uuid_v1_time(&uuid, &clock_seq, timestamp, node)) {
printf("Failed to generate a v1 (time based) UUID\n");
}
Returns
Type | Description |
---|---|
int | 0: OK (generated), otherwise: error, algorithm not available |
Get a list of system DNS servers
Reads the DNS servers in the system configuration. Will read at most @p
n
servers, even if more are configured. Keep in mind that modern systems have complex configurations and often (especially on Linux) this will yield just one DNS server which listens on the loopback IP address, while the "real" DNS configuration is not available through standard means.
On POSIX systems, this will read from /etc/resolv.conf
, looking for nameserver
lines. On Windows, this will use system functions to get the info. On other systems, if available, will read the system configuration as best it can.
Method(s)
To Configure proxy to be used from the system
you can use the following method(s) in the C-Core SDK:
Declaration
int pubnub_dns_read_system_servers_ipv4(struct pubnub_ipv4_address* o_ipv4, size_tn);
Parameters
Parameters | Type | Required | Description |
---|---|---|---|
o_ipv4 | struct pubnub_ipv4_address* | Yes | The array where to put the system DNS servers. allocated by the caller for @p n elements. |
n | size_t | Yes | The number of elements allocated for the @p o_ipv4 . |
Basic Usage
struct pubnub_ipv4_address addr[MAX_DNS_SRV];
int c = pubnub_dns_read_system_servers(addr, MAX_DNS_SRV);
if (c != 0) {
printf("Can't get list of system DNS servers!\n");
}
else {
int i;
for (i = 0; i < c; ++i) {
printf("System DNS server %d.: %d.%d.%d.%d\n", i, addr[i].ipv4[0], addr[i].ipv4[1], addr[i].ipv4[2], addr[i].ipv4[3]
}
}