static enum pubnub_res end_await(struct UserData *pUserData) { #if defined _WIN32 WaitForSingleObject(pUserData->condw, INFINITE); #else pthread_mutex_lock(&pUserData->mutw); while (!pUserData->triggered) { pthread_cond_wait(&pUserData->condw, &pUserData->mutw); } pthread_mutex_unlock(&pUserData->mutw); #endif return pubnub_last_result(pUserData->pb); }
bool pnfntst_subscribe_and_check(pubnub_t *p, char const *channel, char const*chgroup, unsigned ms, ...) { char const *aMsgs[16]; char const *aChan[16]; uint16_t missing; size_t count = 0; pnfntst_timer_t *tmr; va_list vl; PUBNUB_ASSERT(pb_valid_ctx_ptr(p)); va_start(vl, ms); while (count < 16) { char const *msg = va_arg(vl, char*); if (NULL == msg) { break; } aMsgs[count] = msg; msg = va_arg(vl, char*); if (NULL == msg) { return false; } aChan[count] = msg; ++count; } va_end(vl); if ((0 == count) || (count > 16)) { return false; } missing = (0x01 << count) - 1; tmr = pnfntst_alloc_timer(); if (NULL == tmr) { puts("subscribe and check: timer alloc failed"); return false; } pnfntst_start_timer(tmr, ms); while (pnfntst_timer_is_running(tmr) && missing) { enum pubnub_res pbres; if (PNR_STARTED != pubnub_subscribe(p, channel, chgroup)) { puts("subscribe and check: subscribe failed"); break; } while (pnfntst_timer_is_running(tmr)) { pbres = pubnub_last_result(p); if (pbres != PNR_STARTED) { break; } } if (pbres != PNR_OK) { printf("subscribe and check: subscribe error %d\n", pbres); break; } do { size_t i; char const *msg = pubnub_get(p); char const *chan = pubnub_get_channel(p); if ((NULL == msg) || (NULL == chan)) { break; } for (i = 0; i < count; ++i) { if ((missing & (0x01 << i)) && (strcmp(msg, aMsgs[i]) == 0) && (strcmp(chan, aChan[i]) == 0) ) { missing &= ~(0x01 << i); break; } } } while (missing); } pnfntst_free_timer(tmr); return !missing; }
pubnub_res futres::end_await() { d_pimpl->end_await(); return pubnub_last_result(d_pb); }
pubnub_res futres::last_result() { return pubnub_last_result(d_pb); }
int main() { /* This is a widely use channel, something should happen there from time to time */ char const *chan = "hello_world"; pubnub_t *pbp = pubnub_alloc(); if (NULL == pbp) { printf("Failed to allocate Pubnub context!\n"); return -1; } pubnub_init(pbp, "demo", "demo"); srand(time(NULL)); /* This is essential, as otherwise waiting for incoming data will block! Since we're doing this, be sure to not enable verbose debugging, as you won't see a thing except endless lines of some tracing. */ pubnub_set_non_blocking_io(pbp); puts("--------------------------"); puts("Subscribe loop starting..."); puts("--------------------------"); for (;;) { time_t t = time(NULL); bool stop = false; enum pubnub_res res = pubnub_subscribe(pbp, chan, NULL); if (res != PNR_STARTED) { printf("pubnub_subscribe() returned unexpected: %d\n", res); break;; } /* Don't await here, 'cause it will loop until done */ while (!stop) { res = pubnub_last_result(pbp); if (res == PNR_STARTED) { /* Here we simulate the "get out of subscribe loop" external signal with a random number. Basically, this has a 4% chance of stopping the wait every second. */ if (time(NULL) != t) { stop = (rand() % 25) == 3; t = time(NULL); } } else { if (PNR_OK == res) { puts("Subscribed! Got messages:"); for (;;) { char const *msg = pubnub_get(pbp); if (NULL == msg) { break; } puts(msg); } } else { printf("Subscribing failed with code: %d\n", res); } break; } } if (stop) { puts("---------------------------"); puts("Cancelling the Subscribe..."); puts("---------------------------"); pubnub_cancel(pbp); /* Now it's OK to await, since we don't have anything else to do */ pubnub_await(pbp); break; } } /* We're done */ if (pubnub_free(pbp) != 0) { printf("Failed to free the Pubnub context `pbp`\n"); } puts("Pubnub callback demo over."); return 0; }