source: rtos_arduino/trunk/arduino_lib/libraries/PubNub/PubNub.h@ 221

Last change on this file since 221 was 221, checked in by ertl-honda, 8 years ago

ESP8266を使用するよう変更.

File size: 8.5 KB
Line 
1#ifndef PubNub_h
2#define PubNub_h
3
4
5#include <stdint.h>
6
7
8/* By default, the PubNub library is built to work with the Ethernet
9 * shield. WiFi shield support can be enabled by commenting the
10 * following line and commenting out the line after that. Refer
11 * to the PubNubJsonWifi sketch for a complete example. */
12//#define PubNub_Ethernet
13//#define PubNub_WiFi
14#define PubNub_ESP8266
15
16#if defined(PubNub_Ethernet)
17#include <Ethernet.h>
18#define PubNub_BASE_CLIENT EthernetClient
19
20#elif defined(PubNub_WiFi)
21#include <WiFi.h>
22#define PubNub_BASE_CLIENT WiFiClient
23
24#elif defined(PubNub_ESP8266)
25#include "ESP8266.h"
26#include "Client_ESP8266.h"
27#define PubNub_BASE_CLIENT ESP8266Client
28
29#else
30#error PubNub_BASE_CLIENT set to an invalid value!
31#endif
32
33
34/* Some notes:
35 *
36 * (i) There is no SSL support on Arduino, it is unfeasible with
37 * Arduino Uno or even Arduino Mega's computing power and memory limits.
38 * All the traffic goes on the wire unencrypted and unsigned.
39 *
40 * (ii) We re-resolve the origin server IP address before each request.
41 * This means some slow-down for intensive communication, but we rather
42 * expect light traffic and very long-running sketches (days, months),
43 * where refreshing the IP address is quite desirable.
44 *
45 * (iii) We let the users read replies at their leisure instead of
46 * returning an already preloaded string so that (a) they can do that
47 * in loop() code while taking care of other things as well (b) we don't
48 * waste precious RAM by pre-allocating buffers that are never needed.
49 *
50 * (iv) If you are having problems connecting, maybe you have hit
51 * a bug in Debian's version of Arduino pertaining the DNS code. Try using
52 * an IP address as origin and/or upgrading your Arduino package.
53 *
54 * (v) The optional timeout parameter allows you to specify a timeout
55 * period after which the subscribe call shall be retried. Note
56 * that this timeout is applied only for reading response, not for
57 * connecting or sending data; use retransmission parameters of
58 * the Ethernet library to tune this. As a rule of thumb, timeout
59 * smaller than 30 seconds may still block longer with flaky
60 * network. Default server-side timeout of PubNub API is 300s.
61 *
62 * (vi) If some of the PubNub calls fail with your WiFi shield (e.g. you
63 * see "subscribe error" and similar messages in serial console), your
64 * WiFi shield firmware may be buggy - e.g. a WiFi shield bought
65 * commercially in May 2013 had a firmware that had to be upgaded.
66 * This is not so difficult to do, simply follow:
67 *
68 * http://arduino.cc/en/Hacking/WiFiShieldFirmwareUpgrading
69 *
70 * (vii) The vendor firmware for the WiFi shield has dubious TCP implementation;
71 * for example, TCP ports of outgoing connections are always chosen from the
72 * same sequence, so if you reset your Arduino, some of the new connections
73 * may interfere with an outstanding TCP connection that has not been closed
74 * before the reset; i.e. you will typically see a single failed request
75 * somewhere down the road after a reset.
76 *
77 * (viii) It is essential to use a new enough Arduino version so that
78 * the WiFi library actually works properly. Most notably, version 1.0.5
79 * has been confirmed to work while Arduino 1.0.4 is broken.
80 */
81
82
83/* This class is a thin EthernetClient wrapper whose goal is to
84 * automatically acquire time token information when reading
85 * subscribe call response.
86 *
87 * (i) The user application sees only the JSON body, not the timetoken.
88 * As soon as the body ends, PubSubclient reads the rest of HTTP reply
89 * itself and disconnects. The stored timetoken is used in the next call
90 * to the PubSub::subscribe method then. */
91class PubSubClient : public PubNub_BASE_CLIENT {
92public:
93 PubSubClient() :
94 PubNub_BASE_CLIENT(), json_enabled(false)
95 {
96 strcpy(timetoken, "0");
97 }
98
99 /* Customized functions that make reading stop as soon as we
100 * have hit ',' outside of braces and string, which indicates
101 * end of JSON body. */
102 virtual int read();
103 virtual int read(uint8_t *buf, size_t size);
104 virtual void stop();
105
106 /* Block until data is available. Returns false in case the
107 * connection goes down or timeout expires. */
108 bool wait_for_data(int timeout = 310);
109
110 /* Enable the JSON state machine. */
111 void start_body();
112
113 inline char *server_timetoken() { return timetoken; }
114
115private:
116 void _state_input(uint8_t ch, uint8_t *nextbuf, size_t nextsize);
117 void _grab_timetoken(uint8_t *nextbuf, size_t nextsize);
118
119 /* JSON state machine context */
120 bool json_enabled:1;
121 bool in_string:1;
122 bool after_backslash:1;
123 int braces_depth;
124
125 /* Time token acquired during the last subscribe request. */
126 char timetoken[22];
127};
128
129
130enum PubNub_BH {
131 PubNub_BH_OK,
132 PubNub_BH_ERROR,
133 PubNub_BH_TIMEOUT,
134};
135
136class PubNub {
137public:
138 /* Init the Pubnub Client API
139 *
140 * This should be called after Ethernet.begin().
141 * Note that the string parameters are not copied; do not
142 * overwrite or free the memory where you stored the keys!
143 * (If you are passing string literals, don't worry about it.)
144 * Note that you should run only a single publish at once.
145 *
146 * @param string publish_key required key to send messages.
147 * @param string subscribe_key required key to receive messages.
148 * @param string origin optional setting for cloud origin.
149 * @return boolean whether begin() was successful. */
150 bool begin(const char *publish_key, const char *subscribe_key, const char *origin = "pubsub.pubnub.com");
151
152 /* Set the UUID identification of PubNub client. This is useful
153 * e.g. for presence identification.
154 *
155 * Pass NULL to unset. The string is not copied over (just like
156 * in begin()). See the PubNubSubscriber example for simple code
157 * that generates a random UUID (although not 100% reliable). */
158 void set_uuid(const char *uuid);
159
160 /* Set the authorization key/token of PubNub client. This is useful
161 * e.g. for access rights validation (PAM).
162 *
163 * Pass NULL to unset. The string is not copied over (just like
164 * in begin()). */
165 void set_auth(const char *auth);
166
167 /* Publish
168 *
169 * Send a message (assumed to be well-formed JSON) to a given channel.
170 *
171 * Note that the reply can be obtained using code like:
172 client = publish("demo", "\"lala\"");
173 if (!client) return; // error
174 while (client->connected()) {
175 // More sophisticated code will want to add timeout handling here
176 while (client->connected() && !client->available()) ; // wait
177 char c = client->read();
178 Serial.print(c);
179 }
180 client->stop();
181 * You will get content right away, the header has been already
182 * skipped inside the function. If you do not care about
183 * the reply, just call client->stop(); immediately.
184 *
185 * It returns an object that is typically EthernetClient (but it
186 * can be a WiFiClient if you enabled the WiFi shield).
187 *
188 * @param string channel required channel name.
189 * @param string message required message string in JSON format.
190 * @param string timeout optional timeout in seconds.
191 * @return string Stream-ish object with reply message or NULL on error. */
192 PubNub_BASE_CLIENT *publish(const char *channel, const char *message, int timeout = 30);
193
194 /**
195 * Subscribe
196 *
197 * Listen for a message on a given channel. The function will block
198 * and return when a message arrives. Typically, you will run this
199 * function from loop() function to keep listening for messages
200 * indefinitely.
201 *
202 * As a reply, you will get a JSON array with messages, e.g.:
203 * ["msg1",{msg2:"x"}]
204 * and so on. Empty reply [] is also normal and your code must be
205 * able to handle that. Note that the reply specifically does not
206 * include the time token present in the raw reply.
207 *
208 * @param string channel required channel name.
209 * @param string timeout optional timeout in seconds.
210 * @return string Stream-ish object with reply message or NULL on error. */
211 PubSubClient *subscribe(const char *channel, int timeout = 310);
212
213 /**
214 * History
215 *
216 * Receive list of the last N messages on the given channel.
217 *
218 * @param string channel required channel name.
219 * @param int limit optional number of messages to retrieve.
220 * @param string timeout optional timeout in seconds.
221 * @return string Stream-ish object with reply message or NULL on error. */
222 PubNub_BASE_CLIENT *history(const char *channel, int limit = 10, int timeout = 310);
223
224private:
225 enum PubNub_BH _request_bh(PubNub_BASE_CLIENT &client, unsigned long t_start, int timeout, char qparsep);
226
227 const char *publish_key, *subscribe_key;
228 const char *origin;
229 const char *uuid;
230 const char *auth;
231
232 PubNub_BASE_CLIENT publish_client, history_client;
233 PubSubClient subscribe_client;
234};
235
236extern class PubNub PubNub;
237
238#endif
Note: See TracBrowser for help on using the repository browser.