1
0
mirror of https://github.com/arduino-libraries/ArduinoHttpClient.git synced 2025-06-07 07:42:01 +03:00

Add connection keep alive support

This commit is contained in:
Sandeep Mistry 2016-06-17 14:18:11 -04:00
parent 33804d4534
commit bfedff87c1
2 changed files with 64 additions and 20 deletions

View File

@ -10,7 +10,8 @@ const char* HttpClient::kUserAgent = "Arduino/2.2.0";
const char* HttpClient::kContentLengthPrefix = HTTP_HEADER_CONTENT_LENGTH ": "; const char* HttpClient::kContentLengthPrefix = HTTP_HEADER_CONTENT_LENGTH ": ";
HttpClient::HttpClient(Client& aClient, const char* aServerName, uint16_t aServerPort) HttpClient::HttpClient(Client& aClient, const char* aServerName, uint16_t aServerPort)
: iClient(&aClient), iServerName(aServerName), iServerAddress(), iServerPort(aServerPort) : iClient(&aClient), iServerName(aServerName), iServerAddress(), iServerPort(aServerPort),
iConnectionClose(true)
{ {
resetState(); resetState();
} }
@ -21,7 +22,8 @@ HttpClient::HttpClient(Client& aClient, const String& aServerName, uint16_t aSer
} }
HttpClient::HttpClient(Client& aClient, const IPAddress& aServerAddress, uint16_t aServerPort) HttpClient::HttpClient(Client& aClient, const IPAddress& aServerAddress, uint16_t aServerPort)
: iClient(&aClient), iServerName(NULL), iServerAddress(aServerAddress), iServerPort(aServerPort) : iClient(&aClient), iServerName(NULL), iServerAddress(aServerAddress), iServerPort(aServerPort),
iConnectionClose(true)
{ {
resetState(); resetState();
} }
@ -42,6 +44,11 @@ void HttpClient::stop()
resetState(); resetState();
} }
void HttpClient::connectionKeepAlive()
{
iConnectionClose = false;
}
void HttpClient::beginRequest() void HttpClient::beginRequest()
{ {
iState = eRequestStarted; iState = eRequestStarted;
@ -49,28 +56,44 @@ void HttpClient::beginRequest()
int HttpClient::startRequest(const char* aURLPath, const char* aHttpMethod) int HttpClient::startRequest(const char* aURLPath, const char* aHttpMethod)
{ {
if (!iConnectionClose)
{
flushClientRx();
resetState();
}
tHttpState initialState = iState; tHttpState initialState = iState;
if ((eIdle != iState) && (eRequestStarted != iState)) if ((eIdle != iState) && (eRequestStarted != iState))
{ {
return HTTP_ERROR_API; return HTTP_ERROR_API;
} }
if (iServerName) { if (iConnectionClose || !iClient->connected())
if (!iClient->connect(iServerName, iServerPort) > 0) {
{ if (iServerName) {
#ifdef LOGGING if (!iClient->connect(iServerName, iServerPort) > 0)
Serial.println("Connection failed"); {
#endif #ifdef LOGGING
return HTTP_ERROR_CONNECTION_FAILED; Serial.println("Connection failed");
#endif
return HTTP_ERROR_CONNECTION_FAILED;
}
} else {
if (!iClient->connect(iServerAddress, iServerPort) > 0)
{
#ifdef LOGGING
Serial.println("Connection failed");
#endif
return HTTP_ERROR_CONNECTION_FAILED;
}
} }
} else { }
if (!iClient->connect(iServerAddress, iServerPort) > 0) else
{ {
#ifdef LOGGING #ifdef LOGGING
Serial.println("Connection failed"); Serial.println("Connection already open");
#endif #endif
return HTTP_ERROR_CONNECTION_FAILED;
}
} }
// Now we're connected, send the first part of the request // Now we're connected, send the first part of the request
@ -111,9 +134,12 @@ int HttpClient::sendInitialHeaders(const char* aURLPath, const char* aHttpMethod
// And user-agent string // And user-agent string
sendHeader(HTTP_HEADER_USER_AGENT, kUserAgent); sendHeader(HTTP_HEADER_USER_AGENT, kUserAgent);
// We don't support persistent connections, so tell the server to if (iConnectionClose)
// close this connection after we're done {
sendHeader(HTTP_HEADER_CONNECTION, "close"); // Tell the server to
// close this connection after we're done
sendHeader(HTTP_HEADER_CONNECTION, "close");
}
// Everything has gone well // Everything has gone well
iState = eRequestStarted; iState = eRequestStarted;
@ -194,6 +220,17 @@ void HttpClient::finishHeaders()
iState = eRequestSent; iState = eRequestSent;
} }
void HttpClient::flushClientRx()
{
if (iClient->connected())
{
while (iClient->available())
{
iClient->read();
}
}
}
void HttpClient::endRequest() void HttpClient::endRequest()
{ {
if (iState < eRequestSent) if (iState < eRequestSent)

View File

@ -48,6 +48,8 @@ public:
HttpClient(Client& aClient, const String& aServerName, uint16_t aServerPort = kHttpPort); HttpClient(Client& aClient, const String& aServerName, uint16_t aServerPort = kHttpPort);
HttpClient(Client& aClient, const IPAddress& aServerAddress, uint16_t aServerPort = kHttpPort); HttpClient(Client& aClient, const IPAddress& aServerAddress, uint16_t aServerPort = kHttpPort);
void connectionKeepAlive();
/** Start a more complex request. /** Start a more complex request.
Use this when you need to send additional headers in the request, Use this when you need to send additional headers in the request,
but you will also need to call endRequest() when you are finished. but you will also need to call endRequest() when you are finished.
@ -247,6 +249,10 @@ protected:
*/ */
void finishHeaders(); void finishHeaders();
/** Reading any pending data from the client (used in connection keep alive mode)
*/
void flushClientRx();
// Number of milliseconds that we wait each time there isn't any data // Number of milliseconds that we wait each time there isn't any data
// available to be read (during status code and header processing) // available to be read (during status code and header processing)
static const int kHttpWaitForDataDelay = 1000; static const int kHttpWaitForDataDelay = 1000;
@ -284,6 +290,7 @@ protected:
// How far through a Content-Length header prefix we are // How far through a Content-Length header prefix we are
const char* iContentLengthPtr; const char* iContentLengthPtr;
uint32_t iHttpResponseTimeout; uint32_t iHttpResponseTimeout;
bool iConnectionClose;
String iHeaderLine; String iHeaderLine;
}; };