Skip to content

Commit

Permalink
heartbeat related changes (#152)
Browse files Browse the repository at this point in the history
* removed state param from subscribe

* state taken if exists from pubnub context

* set state with heartbeat implementation

* add basic test for set_state_ex

* set state with heartbeat examples
  • Loading branch information
budgetpreneur authored Jan 16, 2023
1 parent af81bfd commit 7af9fba
Show file tree
Hide file tree
Showing 28 changed files with 557 additions and 138 deletions.
25 changes: 17 additions & 8 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
name: c-core
schema: 1
version: "4.0.6"
version: "4.1.0"
scm: github.com/pubnub/c-core
changelog:
- date: 2023-01-16
version: v4.1.0
changes:
- type: feature
text: "Added pubnub_set_state_ex to support heartbeat."
- type: bug
text: "Removed state param from subscribe request."
- type: bug
text: "Added state param to hearbeat request."
- date: 2022-12-14
version: v4.0.6
changes:
Expand Down Expand Up @@ -688,7 +697,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -754,7 +763,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -820,7 +829,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -882,7 +891,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -943,7 +952,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -999,7 +1008,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down Expand Up @@ -1052,7 +1061,7 @@ sdks:
distribution-type: source code
distribution-repository: GitHub release
package-name: C-Core
location: https://github.com/pubnub/c-core/releases/tag/v4.0.6
location: https://github.com/pubnub/c-core/releases/tag/v4.1.0
requires:
-
name: "miniz"
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v4.1.0
January 16 2023

#### Added
- Added pubnub_set_state_ex to support heartbeat.

#### Fixed
- Removed state param from subscribe request.
- Added state param to hearbeat request.

## v4.0.6
December 14 2022

Expand Down
3 changes: 2 additions & 1 deletion core/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PROJECT_SOURCEFILES = pubnub_pubsubapi.c pubnub_coreapi.c pubnub_ccore_pubsub.c pubnub_ccore.c pubnub_netcore.c pubnub_alloc_static.c pubnub_assert_std.c pubnub_json_parse.c pubnub_keep_alive.c pubnub_helper.c pubnub_url_encode.c ../lib/pb_strnlen_s.c ../lib/pb_strncasecmp.c ../lib/base64/pbbase64.c
PROJECT_SOURCEFILES = pbcc_set_state.c pubnub_pubsubapi.c pubnub_coreapi.c pubnub_ccore_pubsub.c pubnub_ccore.c pubnub_netcore.c pubnub_alloc_static.c pubnub_assert_std.c pubnub_json_parse.c pubnub_keep_alive.c pubnub_helper.c pubnub_url_encode.c ../lib/pb_strnlen_s.c ../lib/pb_strncasecmp.c ../lib/base64/pbbase64.c pubnub_coreapi_ex.c
# TODO: move coreapi_ex to new module

all: pubnub_grant_token_api_unittest pubnub_proxy_unittest pubnub_timer_list_unittest unittest

Expand Down
125 changes: 125 additions & 0 deletions core/pbcc_set_state.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include "pbcc_set_state.h"
#include "pubnub_internal.h"
#include "pubnub_log.h"
#include <string.h>
#include <stdlib.h>

static int json_kvp_builder(char* jsonbuilder, int pos, char* key, char* val)
{
int dq_len = strlen("\"");
int co_len = strlen(":");
int key_len = strlen(key);
int val_len = strlen(val);

memcpy(jsonbuilder + pos, "\"", dq_len);
pos += dq_len;
memcpy(jsonbuilder + pos, key, key_len);
pos += key_len;
memcpy(jsonbuilder + pos, "\"", dq_len);
pos += dq_len;
memcpy(jsonbuilder + pos, ":", co_len);
pos += co_len;
memcpy(jsonbuilder + pos, val, val_len);
pos += val_len;
return pos;
}


void pbcc_adjust_state(pubnub_t* pb,
char const* channel,
char const* channel_group,
char const* state)
{
int ch_cnt = 0, cg_cnt = 0, tot_ch = 0, tot_cg = 0;
if (channel){
tot_ch = 1;
for (int i=0; i < (int)strlen(channel); i++) { tot_ch = (channel[i] == ',') ? tot_ch + 1 : tot_ch; }
}
if (channel_group){
tot_cg = 1;
for (int i=0; i < (int)strlen(channel_group); i++) { tot_cg = (channel_group[i] == ',') ? tot_cg + 1 : tot_cg; }
}

int buff_size = ((tot_ch + tot_cg) * strlen(state)) + (channel ? strlen(channel) : 1) + (channel_group ? strlen(channel_group) : 1) + 20;
char * json_state = (char*)malloc(buff_size);
if (pb->core.state != NULL && buff_size != sizeof(pb->core.state)){
pb->core.state = (char*)realloc((char*)pb->core.state, buff_size);
}
else if (pb->core.state == NULL){
pb->core.state = (char*)malloc(buff_size);
}
int mem_len = 0;
if (json_state != NULL && pb->core.state != NULL){
mem_len = strlen("{");
memcpy(json_state, "{", mem_len);
int cm_len = strlen(",");
if (channel && strncmp(channel, (char*)",", 1) != 0) {
char* str_ch = (char*)channel;
char* ch_temp;
size_t ch_len;
bool end = false;
do{
ch_temp = strchr(str_ch,',');
if (ch_cnt > 0) {
memcpy(json_state + mem_len, ",", cm_len);
mem_len += cm_len;
}
if (ch_temp == NULL) { end = true; ch_len = strlen(str_ch); }
else { ch_len = ch_temp - str_ch; }

if (ch_len == 0) { continue; }

char* curr_ch = (char*)malloc(ch_len + 1);
strncpy(curr_ch, str_ch, ch_len);
curr_ch[ch_len] = '\0';

mem_len = json_kvp_builder(json_state, mem_len, curr_ch, (char*)state);

ch_cnt++;
str_ch = ch_temp + 1;
free(curr_ch);
} while (false == end);
}

if (channel_group) {
char* str_cg = (char*)channel_group;
char* cg_temp;
int cg_len;
bool end = false;
do{
cg_temp = strchr(str_cg,',');
if (ch_cnt > 0 || cg_cnt > 0) {
memcpy(json_state + mem_len, ",", cm_len);
mem_len += cm_len;
}
if (cg_temp == NULL) { end = true; cg_len = strlen(str_cg); }
else { cg_len = cg_temp - str_cg; }

if (cg_len == 0) { continue; }

char* curr_cg = (char*)malloc(cg_len + 1);
strncpy(curr_cg, str_cg, cg_len);
curr_cg[cg_len] = '\0';

mem_len = json_kvp_builder(json_state, mem_len, curr_cg, (char*)state);

cg_cnt++;
str_cg = cg_temp + 1;
free(curr_cg);
} while (false == end);
}

int cb_len = strlen("}");
memcpy(json_state + mem_len, "}", cb_len);
mem_len += cb_len;
json_state[mem_len] = '\0';
PUBNUB_LOG_DEBUG("formatted state is %s\n", json_state);

strcpy((char*)pb->core.state, (const char*)json_state);
free(json_state);
json_state = NULL;
}

}


14 changes: 14 additions & 0 deletions core/pbcc_set_state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
#if !defined INC_PBCC_SET_STATE
#define INC_PBCC_SET_STATE

#include "pubnub_api_types.h"

/** Adjusting the @pb presence state for pubnub usage
*/
void pbcc_adjust_state(pubnub_t* pb,
char const* channel,
char const* channel_group,
char const* state);

#endif // INC_PBCC_SET_STATE
1 change: 1 addition & 0 deletions core/pubnub_ccore.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ enum pubnub_res pbcc_heartbeat_prep(struct pbcc_context* pb,
if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); }
if (channel_group) { ADD_URL_PARAM(qparam, channel-group, channel_group); }
if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); }
if (pb->state) { ADD_URL_PARAM(qparam, state, pb->state); }
#if PUBNUB_CRYPTO_API
if (pb->secret_key == NULL) { ADD_URL_AUTH_PARAM(pb, qparam, auth); }
ADD_TS_TO_URL_PARAM();
Expand Down
1 change: 0 additions & 1 deletion core/pubnub_ccore_pubsub.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,6 @@ enum pubnub_res pbcc_subscribe_prep(struct pbcc_context* p,
if (uname) { ADD_URL_PARAM(qparam, pnsdk, uname); }
if (channel_group) { ADD_URL_PARAM(qparam, channel-group, channel_group); }
if (user_id) { ADD_URL_PARAM(qparam, uuid, user_id); }
if (p->state) { ADD_URL_PARAM(qparam, state, p->state); }
#if PUBNUB_CRYPTO_API
if (p->secret_key == NULL) { ADD_URL_AUTH_PARAM(p, qparam, auth); }
ADD_TS_TO_URL_PARAM();
Expand Down
50 changes: 50 additions & 0 deletions core/pubnub_core_unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "pubnub_server_limits.h"
#include "pubnub_pubsubapi.h"
#include "pubnub_coreapi.h"
// TODO: move coreapi_ex to new module
#include "pubnub_coreapi_ex.h"
#if PUBNUB_USE_ADVANCED_HISTORY
#include "pubnub_memory_block.h"
#include "pubnub_advanced_history.h"
Expand Down Expand Up @@ -1785,7 +1787,55 @@ Ensure(single_context_pubnub, state_get_bad_response)
attest(pbp->core.user_id_len, equals(8));
}

// TODO: move coreapi_ex to new module
Ensure(single_context_pubnub, set_state_ex_defaults)
{
pubnub_init(pbp, "publhis", "subhis");

/* with uuid from context */
pubnub_set_user_id(pbp, "universal");
expect_have_dns_for_pubnub_origin();
expect_outgoing_with_url("/v2/presence/sub-key/subhis/channel/ch/uuid/"
"universal/data?pnsdk=unit-test-0.1&uuid=universal&state=%7B%7D");
incoming("HTTP/1.1 200\r\nContent-Length: 67\r\n\r\n{\"status\": "
"200,\"message\":\"OK\", \"service\": \"Presence\", "
"\"payload\":{}}",
NULL);
expect(pbntf_lost_socket, when(pb, equals(pbp)));
expect(pbntf_trans_outcome, when(pb, equals(pbp)));

attest(pubnub_set_state_ex(pbp, "ch", "{}", pubnub_set_state_defopts()), equals(PNR_OK));

attest(pubnub_get(pbp), streqs("{\"status\": 200,\"message\":\"OK\", \"service\": \"Presence\", \"payload\":{}}"));
attest(pubnub_get(pbp), equals(NULL));
attest(pubnub_last_http_code(pbp), equals(200));
}

// TODO: move coreapi_ex to new module
Ensure(single_context_pubnub, state_get_with_heartbeat)
{
pubnub_init(pbp, "pub-key", "sub-key");
pubnub_set_user_id(pbp, "test-id");

expect_have_dns_for_pubnub_origin();
expect_outgoing_with_url("/v2/presence/sub-key/sub-key/channel/ch/"
"heartbeat?pnsdk=unit-test-0.1&uuid=test-id&state=%7B%22ch%22%3A%7B%7D%7D");
incoming("HTTP/1.1 200\r\nContent-Length: 67\r\n\r\n{\"status\": "
"200,\"message\":\"OK\", \"service\": \"Presence\", "
"\"payload\":{}}",
NULL);
expect(pbntf_lost_socket, when(pb, equals(pbp)));
expect(pbntf_trans_outcome, when(pb, equals(pbp)));

struct pubnub_set_state_options options = pubnub_set_state_defopts();
options.heartbeat = true;
attest(pubnub_set_state_ex(pbp, "ch", "{}", options), equals(PNR_OK));

attest(pubnub_get(pbp), streqs("{\"status\": 200,\"message\":\"OK\", \"service\": \"Presence\", \"payload\":{}}"));
attest(pubnub_get(pbp), equals(NULL));
attest(pubnub_last_http_code(pbp), equals(200));
}

/* HERE_NOW operation */

Ensure(single_context_pubnub, here_now_channel)
Expand Down
Loading

0 comments on commit 7af9fba

Please sign in to comment.