Persistent Connection

Persistent Connection allows to send multiple HTTP requests one after the other on the same open connection before closing it. For more details, refer to section Persistent Connection in the HTTP Reference Guide.

Example

In this example, two HTTP requests are queued on an HTTP Connection before the client closes the connection.

The function HTTPc_ReqSend is called with the flag HTTPc_FLAG_REQ_NO_BLOCK, so the function is not blocking and will return before the transaction is complete. Therefore the On Transaction Complete hook must be set up to retrieve the HTTP response.

Listing - Persistent Connection Example Code
#define  HTTP_SERVER_HOSTNAME                            "www.example.com"

#define  HTTPc_EX_CFG_CONN_NBR_MAX                        5u
#define  HTTPc_EX_CFG_REQ_NBR_MAX                         5u
#define  HTTPc_EX_CFG_BUF_SIZE                          512u

HTTPc_CONN_OBJ  HTTPcEx_ConnTbl[HTTPc_EX_CFG_CONN_NBR_MAX];
HTTPc_REQ_OBJ   HTTPcEx_ReqTbl[HTTPc_EX_CFG_REQ_NBR_MAX];
HTTPc_RESP_OBJ  HTTPcEx_RespTbl[HTTPc_EX_CFG_REQ_NBR_MAX];
CPU_CHAR        HTTPcEx_BufTbl[HTTPc_EX_CFG_CONN_NBR_MAX][HTTPc_EX_CFG_BUF_SIZE ];

CPU_BOOLEAN     close_conn = DEF_NO;
CPU_BOOLEAN     req1_done = DEF_NO;
CPU_BOOLEAN     req2_done = DEF_NO;

/*
*********************************************************************************************************
*                                         HTTPcEx_ReqSendGET()
*
* Description : Example function to Send Requests on persistent connection.
*
* Argument(s) : None.
*
* Return(s)   : DEF_YES, if request successfully sent.
*			    DEF_NO,  otherwise.
*********************************************************************************************************
*/

CPU_BOOLEAN  HTTPcEx_ReqSendGET (void)
{
    HTTPc_CONN_OBJ     *p_conn;
    HTTPc_REQ_OBJ      *p_req1;
    HTTPc_REQ_OBJ      *p_req2;
    HTTPc_RESP_OBJ     *p_resp1;
    HTTPc_RESP_OBJ     *p_resp2;
    CPU_CHAR           *p_buf;
    CPU_BOOLEAN         persistent;
    CPU_BOOLEAN         result;

    p_conn  = &HTTPcEx_ConnTbl[0];
    p_buf   = &HTTPcEx_BufTbl[0][0];
    p_req1  = &HTTPcEx_ReqTbl[0]; 
    p_req2  = &HTTPcEx_ReqTbl[1];
    p_resp1 = &HTTPcEx_RespTbl[0];
    p_resp2 = &HTTPcEx_RespTbl[1];

                                                                /* ---------------- INIT NEW CONNECTION --------------- */
    HTTPc_ConnClr(p_conn, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

                                                                /* --------------- SET PERSISTENT MODE ---------------- */
    persistent = DEF_YES;
    HTTPc_ConnSetParam(p_conn,
                       HTTPc_PARAM_TYPE_PERSISTENT,
                      &persistent,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

                                                                /* --------------- SET CONN'S CALLBACKS --------------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
    HTTPc_ConnSetParam(p_conn,
                       HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
                      &HTTPcEx_ConnCloseCallback,
                      &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
#endif

                                                                /* ----------------- INIT NEW REQUESTS ---------------- */
    HTTPc_ReqClr(p_req1, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqClr(p_req2, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

                                                                /* --------- SET REQ/RESP CALLBACK FUNCTIONS ---------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
    HTTPc_ReqSetParam(p_req1, 
                      HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK, 
                     &HTTPcEx_TransDoneCallback, 
                     &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqSetParam(p_req2, 
					  HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK, 
					 &HTTPcEx_TransDoneCallback, 
					 &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqSetParam(p_req1, 
					  HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK, 
					 &HTTPcEx_TransErrCallback, 
					 &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    HTTPc_ReqSetParam(p_req2, 
				      HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK, 
					 &HTTPcEx_TransErrCallback, 
					 &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
#endif

                                                                /* ----------------- OPEN CONNECTION ------------------ */  
    str_len = Str_Len(HTTP_SERVER_HOSTNAME);
    flags  = HTTPc_FLAG_NONE;
    result = HTTPc_ConnOpen(p_conn,
                            p_buf,
                            HTTPc_EX_CFG_BUF_SIZE,
                            HTTP_SERVER_HOSTNAME,
                            str_len,
                            flags,
                           &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }
    if (result == DEF_OK) {
        printf("Connection to server succeeded.\n\r");
    } else {
        printf("Connection to server failed.\n\r");
    }

                                                                /* ---------------- SEND HTTP REQUESTS ---------------- */
    str_len = Str_Len("//");
    flags   = HTTPc_FLAG_NONE;
    DEF_BIT_SET(flags, HTTPc_FLAG_REQ_NO_BLOCK);
    result = HTTPc_ReqSend(p_conn,
                           p_req1,
                           p_resp1,
                           HTTP_METHOD_GET,
                           "//",
                           str_len,
                           flags,
                          &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    (void)HTTPc_ReqSend(p_conn,
                        p_req2,
                        p_resp2,
                        HTTP_METHOD_GET,
                       "//",
                        str_len,
                        flags,
                       &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    while (close_conn == DEF_NO) 
    {
        /* Do OS delay. */
    };

                                                                /* -------------- CLOSE HTTP CONNECTION --------------- */
    close_conn = DEF_NO;
    HTTPc_ConnClose(p_conn, &err);
    if (err != HTTPc_ERR_NONE) {
        return (DEF_FAIL);
    }

    return (DEF_OK);
}

/*
*********************************************************************************************************
*                                         HTTPcEx_TransDoneCallback()
*
* Description : Example callback function to be notified when an HTTP transaction is completed.
*
* Argument(s) : p_conn_obj   Pointer to current HTTPc Connection object.
*
*               p_req_obj    Pointer to current HTTPc Request object.
* 
*               p_resp_obj   Pointer to current HTTPc Response object.
*
*               status       Status of the HTTP transaction:
*                                DEF_OK,   transaction succeeded.
*                                DEF_FAIL, transaction failed.
*
* Return(s)   : None.
*********************************************************************************************************
*/

void  HTTPcEx_TransDoneCallback (HTTPc_CONN_OBJ  *p_conn_obj,                                   
                                 HTTPc_REQ_OBJ   *p_req_obj,
                                 HTTPc_RESP_OBJ  *p_resp_obj,
                                 CPU_BOOLEAN      status)
{
    HTTPc_REQ_OBJ      *p_req1;
    HTTPc_REQ_OBJ      *p_req2;

    p_req1  = &HTTPcEx_ReqTbl[0]; 
    p_req2  = &HTTPcEx_ReqTbl[1];

    if (p_req_obj == p_req1) {
        if (status == DEF_OK) {
            printf("Transaction #1: %s\n\r", p_resp_obj->ReasonPhrasePtr);
        } else {
            printf("Transaction #1 failed\n\r");
        }
        req1_done = DEF_YES;
     } else if (p_req_obj == p_req2) {
        if (status == DEF_OK) {
            printf("Transaction #2: %s\n\r", p_resp_obj->ReasonPhrasePtr);
        } else {
            printf("Transaction #2 failed\n\r");
        }
        req2_done = DEF_YES;
    } else {
        printf("Unexpected error.\n\r");
    }

    close_conn = req1_done & req2_done;
}