Skip to content

Commit

Permalink
Remove retries and enable setting TCP/IP port (#26)
Browse files Browse the repository at this point in the history
Retries were not limited, making it possible to have a
_long_ blocking call, which is not a nice thing in Arduino
`loop()`. Limitting would only partially fix the problem.
Removing them altogether works much better and user can
retry at her own convenience.

Support for setting the TCP/IP port was added, which is needed
when using a TLS/SSL (network) client class. Before, we always
used HTTP port, which would not work.
  • Loading branch information
sveljko authored and vveljko committed Feb 27, 2019
1 parent 0987150 commit 143ef60
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
63 changes: 48 additions & 15 deletions PubNubDefs.h
Expand Up @@ -254,6 +254,7 @@ class PubNub {
d_uuid = 0;
d_auth = 0;
d_last_http_status_code_class = http_scc_unknown;
set_port(http_port);
}

/**
Expand Down Expand Up @@ -281,6 +282,16 @@ class PubNub {
http_scc_server_error = 5
};

/**
* Possible TCP/IP ports to use when connecting to Pubnub.
*/
enum port_for_connection {
/** Connect via HTTP on its default port */
http_port,
/** Connect via TLS (formerly known as SSL) on its default port) */
tls_port
};

/**
* Set the UUID identification of PubNub client. This is useful
* e.g. for presence identification.
Expand All @@ -299,6 +310,23 @@ class PubNub {
* in begin()). */
void set_auth(const char* auth) { d_auth = auth; }

/**
* Set the TCP/IP port to use when connecting to Pubnub.
* Basically, only call this if your client supports SSL/TLS
* as you will need to set the `tls_port`.
*/
void set_port(port_for_connection port) {
switch (port) {
case http_port:
default:
d_port = 80;
break;
case tls_port:
d_port = 443;
break;
}
}

/**
* Publish/Send a message (assumed to be well-formed JSON) to a
* given channel.
Expand Down Expand Up @@ -397,6 +425,9 @@ class PubNub {
const char* d_uuid;
const char* d_auth;

/// TCP/IP port to use.
unsigned d_port;

/// The HTTP status code class of the last PubNub transaction
http_status_code_class d_last_http_status_code_class;

Expand Down Expand Up @@ -575,14 +606,12 @@ inline PubNonSubClient* PubNub::publish(const char* channel,
int timeout)
{
PubNonSubClient& client = publish_client;
unsigned long t_start;
int have_param = 0;
unsigned long t_start = millis();

retry:
t_start = millis();
/* connect() timeout is about 30s, much lower than our usual
* timeout is. */
int rslt = client.connect(d_origin, 80);
int rslt = client.connect(d_origin, d_port);
if (rslt != 1) {
DBGprint("Connection error ");
DBGprintln(rslt);
Expand Down Expand Up @@ -638,30 +667,30 @@ inline PubNonSubClient* PubNub::publish(const char* channel,
case PubNub_BH_OK:
return &client;
case PubNub_BH_ERROR:
DBGprintln("publish() BH_ERROR");
client.stop();
while (client.connected())
;
return 0;
case PubNub_BH_TIMEOUT:
DBGprintln("publish() BH_TIMEOUT");
client.stop();
while (client.connected())
;
goto retry;
return 0;
}
}


inline PubSubClient* PubNub::subscribe(const char* channel, int timeout)
{
PubSubClient& client = subscribe_client;
unsigned long t_start;
int have_param = 0;
unsigned long t_start = millis();

retry:
t_start = millis();
/* connect() timeout is about 30s, much lower than our usual
* timeout is. */
if (!client.connect(d_origin, 80)) {
if (!client.connect(d_origin, d_port)) {
DBGprintln("Connection error");
client.stop();
return 0;
Expand Down Expand Up @@ -716,28 +745,30 @@ inline PubSubClient* PubNub::subscribe(const char* channel, int timeout)
return &client;

case PubNub_BH_ERROR:
DBGprintln("subscribe() BH_ERROR");
client.stop();
while (client.connected())
;
return 0;

case PubNub_BH_TIMEOUT:
DBGprintln("subscribe() BH_TIMEOUT");
client.stop();
DBGprintln("subscribe() BH_TIMEOUT stopped");
while (client.connected())
;
goto retry;
DBGprintln("subscribe() BH_TIMEOUT disconnected");
return 0;
}
}


inline PubNonSubClient* PubNub::history(const char* channel, int limit, int timeout)
{
PubNonSubClient& client = history_client;
unsigned long t_start;
unsigned long t_start = millis();

retry:
t_start = millis();
if (!client.connect(d_origin, 80)) {
if (!client.connect(d_origin, d_port)) {
DBGprintln("Connection error");
client.stop();
return 0;
Expand All @@ -757,15 +788,17 @@ inline PubNonSubClient* PubNub::history(const char* channel, int limit, int time
case PubNub_BH_OK:
return &client;
case PubNub_BH_ERROR:
DBGprintln("history() BH_ERROR");
client.stop();
while (client.connected())
;
return 0;
case PubNub_BH_TIMEOUT:
DBGprintln("history() BH_TIMEOUT");
client.stop();
while (client.connected())
;
goto retry;
return 0;
}
}

Expand Down
15 changes: 8 additions & 7 deletions README.md
Expand Up @@ -323,14 +323,14 @@ that, it expects a working network. We provide examples for some HW.

### ESP8266

In previous section we already showed what to do to use ESP8266, but
in most versions of ESP8266 support for Arduino, some of the (de-facto)
standard library functions that we use are missing. To use our own
implementation of them, `#define` a macro constant before you include
`Pubnub.h`, like this:
In previous section we already showed how to use ESP8266, but in some
(older) versions of ESP8266 support for Arduino, some of the
(de-facto) standard library functions that we use are missing. To use
our own implementation of them, `#define` a macro constant before you
include `PubNub.h`, like this:

#define PUBNUB_DEFINE_STRSPN_AND_STRNCASECMP
#include <Pubnub.h>
#include <PubNub.h>

## Notes

Expand All @@ -346,6 +346,7 @@ implementation of them, `#define` a macro constant before you include
most Arduino compatible boards. But, some shields/boards have SSL
("Secure") clients and you may succeed in using them instead of the
non-secure clients (`WiFiClientSecure` instead of `WiFiClient`).
But don't forget to `PubNub.set_port(PubNub.tls_port)`.

* We re-resolve the origin server IP address before each request.
This means some slow-down for intensive communication, but we rather
Expand All @@ -358,7 +359,7 @@ implementation of them, `#define` a macro constant before you include
waste precious RAM by pre-allocating buffers that are never needed.

* The optional timeout parameter allows you to specify a timeout
period after which the subscribe call shall be retried. Note
period after which the subscribe call shall be cancelled. Note
that this timeout is applied only for reading response, not for
connecting or sending data; use retransmission parameters of
the network library to tune this. As a rule of thumb, timeout
Expand Down
2 changes: 1 addition & 1 deletion library.properties
@@ -1,5 +1,5 @@
name=Pubnub
version=3.0.1
version=3.1.0
author=Vladimir Veljkovic <vlada@pubnub.com>
maintainer=Vladimir Veljkovic <vlada@pubnub.com>
sentence=Pubnub SDK for Arduino.
Expand Down

0 comments on commit 143ef60

Please sign in to comment.