百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

网络通信3:HTTP实现文本传输

bigegpt 2024-09-17 12:26 7 浏览

HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,HTTP协议是建立在TCP协议之上的一种应用。由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种短连接。HTTP遵循请求(Request)/应答(Response)模型。所以一定需要实现请求(Gk8HttpRequest)。同时需要实现返回(Gk8HttpResponse)。在游戏研发编程中HTTP请求类型常用的就是GET和POST。框架设计中就需要实现完成HTTP请求和返回的Gk8HttpClient类。HTTP不管是文本传输还是二进制传输Gk8HttpClient类都能兼容完成响应的功能。HTTP文本传输方便简洁。实现轻量级通信的最佳方式。

libCurl作为是一个多协议的便于客户端使用的URL传输库,基于C语言,提供C语言的API接口。底层通信都是使用libCurl库来完成。具体可找相关资料和参阅相关代码。C语言封装开发的优势就是支持跨平台。Windows平台,安卓平台,IOS平台。跨平台迁移代码无需再次开发。一劳永逸的解决通信问题。为了方便开发时HTTP并发和回调。又实现了Gk8HttpServlet类(httpnet目录中)。高度封装的代码目的就是易于理解便于使用。

C++实现网络HTTP请求类:Gk8HttpRequest.h

 #ifndef __GK8HTTPREQUEST_H__
 #define __GK8HTTPREQUEST_H__
 ?
 #pragma once
 #include "Gk8BaseObj.h"
 #include "Gk8ByteMaker.h"
 #include "Gk8Str.h"
 ?
 typedef GK8_VOID (Gk8BaseObj::*HTTPREQUEST_CALLBACK_FUN)(GK8_LPVOID pHttpResponse);
 ?
 class Gk8HttpRequest
 {
 public:
     //[定义HTTP请求类型]
     typedef enum
     {
         kHttpGet,
         kHttpPost,
         kHttpUnkown,
     }HttpRequestType;
 ?
 protected:
     HttpRequestType m_eRequestType;         //[HTTP请求类型]
     Gk8Str m_sHttpUrl;                      //[HTTP请求地址]
     Gk8ByteMaker m_iRequestData;            //[HTTP请求数据]
     Gk8BaseObj* m_pTarget;                  //[HTTP请求回调目标对象]
     HTTPREQUEST_CALLBACK_FUN m_pSelector;   //[HTTP请求回调函数]
 public:
     Gk8HttpRequest()
     {
         m_eRequestType=kHttpUnkown;
         m_sHttpUrl.Empty();
         m_iRequestData.Destroy();
         m_pTarget=NULL;
         m_pSelector=NULL;
     };
 ?
     virtual ~Gk8HttpRequest()
     {
         ClearRequestData();
     };
     inline GK8_VOID ClearRequestData()
     {
         m_iRequestData.Destroy();
     }
     inline GK8_VOID SetRequestType(HttpRequestType eRequestType)
     {
         m_eRequestType=eRequestType;
     };
 ?
     inline HttpRequestType GetRequestType()
     {
         return m_eRequestType;
     };
 ?
     inline GK8_VOID SetHttpUrl(GK8_LPCSTR lpHttpUrl)
     {
         m_sHttpUrl=lpHttpUrl;
     };
 ?
     inline GK8_LPCSTR GetHttpUrl()
     {
         return m_sHttpUrl;
     };
 ?
     inline GK8_VOID SetRequestData(Gk8ByteMaker* pRequestData)
     {
         pRequestData->ShiftTo(m_iRequestData);
     };
 ?
     inline Gk8ByteMaker* GetRequestData()
     {
         return &m_iRequestData;
     }
 ?
     inline GK8_INT GetRequestDataSize()
     {
         return m_iRequestData.GetStreamSize();
     }
 ?
     inline GK8_VOID SetResponseCallBack(Gk8BaseObj* pTarget,HTTPREQUEST_CALLBACK_FUN pSelector)
     {
         m_pTarget=pTarget;
         m_pSelector=pSelector;
     }
 ?
     inline Gk8BaseObj* GetTarget()
     {
         return m_pTarget;
     }
 ?
     inline HTTPREQUEST_CALLBACK_FUN GetSelector()
     {
         return m_pSelector;
     }
 };
 #endif

C++实现网络HTTP返回类:Gk8HttpResponse.h

 #ifndef __GK8HTTPRESPONSE_H__
 #define __GK8HTTPRESPONSE_H__
 ?
 #pragma once
 #include "Gk8HttpRequest.h"
 ?
 ?
 class Gk8HttpResponse
 {
 protected:
     Gk8HttpRequest* m_pHttpRequest;         //[HTTP请求类]
     GK8_BOOL m_bSucceed;                    //[HTTP请求反馈成功]
     Gk8ByteMaker m_iResponseData;           //[HTTP请求反馈数据]
     GK8_INT m_nResponseCode;                //[HTTP请求反馈码]
     Gk8Str m_sErrorBuffer;                  //[HTTP请求错误信息]
 protected:
     GK8_BOOL InitWithRequest(Gk8HttpRequest* pHttpRequest);
 ?
 public:
 ?
     Gk8HttpResponse(Gk8HttpRequest* pHttpRequest)
     {
         m_pHttpRequest=pHttpRequest;
         m_bSucceed=false;
         m_iResponseData.Destroy();
         m_sErrorBuffer.Empty();
     }
 ?
     virtual ~Gk8HttpResponse()
     {
         if(m_pHttpRequest) delete m_pHttpRequest;
         ClearResponseData();
     }
     inline GK8_VOID ClearResponseData()
     {
         m_iResponseData.Destroy();
     }
 ?
     inline Gk8HttpRequest* GetHttpRequest()
     {
         return m_pHttpRequest;
     }
 ?
     inline GK8_VOID SetSucceed(GK8_BOOL bSucceed)
     {
         m_bSucceed=bSucceed;
     };
 ?
     inline GK8_BOOL IsSucceed()
     {
         return m_bSucceed;
     };
 ?
     inline GK8_VOID SetResponseData(Gk8ByteMaker* pResponseData)
     {
         pResponseData->ShiftTo(m_iResponseData);
     }
 ?
     inline Gk8ByteMaker* GetResponseData()
     {
         return &m_iResponseData;
     }
 ?
     inline GK8_VOID SetResponseCode(GK8_INT nResponseCode)
     {
         m_nResponseCode=nResponseCode;
     }
 ?
     inline GK8_INT GetResponseCode()
     {
         return m_nResponseCode;
     }
 ?
     inline GK8_VOID SetErrorBuffer(GK8_LPCSTR lpErrorBuffer)
     {
         m_sErrorBuffer=lpErrorBuffer;
     };
 ?
     inline GK8_LPCSTR GetErrorBuffer()
     {
         return m_sErrorBuffer;
     }
 };
 ?
 #endif

C++实现HTTP通信类:Gk8HttpClient.h

 #ifndef __GK8HTTPCLIENT_H__
 #define __GK8HTTPCLIENT_H__
 ?
 #pragma once
 #include "Gk8HttpRequest.h"
 #include "Gk8HttpResponse.h"
 ?
 ?
 class Gk8HttpClient
 {
 private:
     GK8_INT m_nTimeOutForConnect;       //[连接超时时间]
     GK8_INT m_nTimeOutForRead;          //[读取超时时间]
 ?
 private:
     Gk8HttpClient();
     virtual ~Gk8HttpClient();
 ?
     GK8_BOOL InitThreadSemphore();
 public:
 ?
     inline GK8_VOID SetTimeoutForConnect(GK8_INT nTimeOutForConnect){m_nTimeOutForConnect=nTimeOutForConnect;};
     inline GK8_INT GetTimeoutForConnect(){return m_nTimeOutForConnect;}
 ?
     inline GK8_VOID SetTimeoutForRead(GK8_INT nTimeOutForRead){m_nTimeOutForRead=nTimeOutForRead;};
     inline GK8_INT GetTimeoutForRead(){return m_nTimeOutForRead;};
 ?
     GK8_VOID Send(Gk8HttpRequest* pHttpRequest);
 ?
     GK8_VOID HttpClientTick();
     static Gk8HttpClient* GetInstance();
 };
 #endif

C++实现HTTP通信类:Gk8HttpClient.cpp

 
 #include "Gk8HttpClient.h"
 #include "curl/curl.h"
 #include "Gk8OperSys.h"
 #include "Gk8SetMb.cpp"
 ?
 #include <queue>
 #include <pthread.h>
 #include <semaphore.h>
 #include <errno.h>
 #include <fcntl.h>
 ?
 ?
 static Gk8HttpClient* sg_pHttpClient=NULL;      //[静态HTTP客户端]
 ?
 static GK8_BOOL sg_bHttpClientQuit=false;       //[退出HTTP]
 static sem_t* sg_pSem=NULL;                     //[信号量的数据类型]
 static GK8_INT sg_AsyncRequestCount=0;          //[同步请求数]
 ?
 //[线程及互斥定义]
 static pthread_t sg_NetWorkThread;              //[HTTP线程]
 static pthread_mutex_t sg_RequestQueueMutex;    //[HTTP请求队列互斥体]
 static pthread_mutex_t sg_ResponseQueueMutex;   //[HTTP响应队列互斥体]
 ?
 static Gk8SetMb<Gk8HttpRequest*> sg_iRequestQueue;      //[HTTP请求队列]
 static Gk8SetMb<Gk8HttpResponse*> sg_iResponseQueue;    //[HTTP响应队列]
 ?
 ?
 static GK8_CHAR sg_szErrorBuf[CURL_ERROR_SIZE];         //[错误信息]
 static Gk8Str sg_iErrorStr;
 ?
 typedef size_t (*HTTPWRITE_CALLBACK)(GK8_LPVOID lpData,size_t nSize,size_t nMemBlock,GK8_LPVOID lpResponseData);
 ?
 #if (GK8_TARGET_PLATFORM==GK8_PLATFORM_IOS)
 #define GK8_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE 1
 #else
 #define GK8_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE 0
 #endif
 ?
 #if GK8_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE
 #define GK8_ASYNC_HTTPREQUEST_SEMAPHORE "Gk8HttpAsync"
 #else
 static sem_t sg_iSem;
 #endif
 ?
 ?
 GK8_BOOL ConfigureCURL(CURL* pCurl);
 GK8_INT ProcessGetTask(Gk8HttpRequest* pHttpRequest,HTTPWRITE_CALLBACK lpCallBack,GK8_LPVOID lpStream,GK8_LPINT lpResponseCode);
 GK8_INT ProcessPostTask(Gk8HttpRequest* pHttpRequest,HTTPWRITE_CALLBACK lpCallBack,GK8_LPVOID lpStream,GK8_LPINT lpResponseCode);
 ?
 ?
 //[接收HTTP数据]
 size_t WriteHttpData(GK8_LPVOID lpData,size_t nSize,size_t nMemBlock,GK8_LPVOID lpResponseData)
 {
     Gk8ByteMaker* pResponseData=(Gk8ByteMaker*)lpResponseData;
     size_t nLength=nSize*nMemBlock;
     pResponseData->WriteBuf(lpData,(GK8_INT)nLength);
     return nLength;
 }
 ?
 //[设置CURL超时属性设置]
 GK8_BOOL ConfigureCURL(CURL* pCurl)
 {
     if(!pCurl) return false;
 ?
     CURLcode nCurlCode=curl_easy_setopt(pCurl,CURLOPT_ERRORBUFFER,sg_szErrorBuf);
     if(nCurlCode!=CURLE_OK) return false;
 ?
     nCurlCode=curl_easy_setopt(pCurl,CURLOPT_TIMEOUT,Gk8HttpClient::GetInstance()->GetTimeoutForRead());
     if(nCurlCode!=CURLE_OK) return false;
 ?
     nCurlCode=curl_easy_setopt(pCurl,CURLOPT_CONNECTTIMEOUT,Gk8HttpClient::GetInstance()->GetTimeoutForConnect());
     if(nCurlCode!=CURLE_OK) return false;
     
     curl_easy_setopt(pCurl,CURLOPT_SSL_VERIFYPEER,0L);
     curl_easy_setopt(pCurl,CURLOPT_SSL_VERIFYHOST,0L);
 ?
     curl_easy_setopt(pCurl,CURLOPT_NOSIGNAL,1L);
     return true;
 }
 ?
 //[处理Get请求]
 GK8_INT ProcessGetTask(Gk8HttpRequest* pHttpRequest,HTTPWRITE_CALLBACK lpCallBack,GK8_LPVOID lpStream,GK8_LPINT lpResponseCode)
 {
     CURLcode nCurlCode=CURL_LAST;
     CURL* pCurl=curl_easy_init();
     
     do
     {
         if(!ConfigureCURL(pCurl)) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_URL,pHttpRequest->GetHttpUrl());
         if(nCurlCode!=CURLE_OK) break;
         
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_WRITEFUNCTION,lpCallBack);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_WRITEDATA,lpStream);
         if(nCurlCode!=CURLE_OK) break;
         
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_FOLLOWLOCATION,true);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_USERAGENT,"libcurl-agent/1.0");
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_perform(pCurl);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_getinfo(pCurl,CURLINFO_RESPONSE_CODE,lpResponseCode);
         //[200:指示客服端的请求已经成功收到,解析,接受]
         if(nCurlCode!=CURLE_OK||*lpResponseCode!=200)
         {
             nCurlCode=CURLE_HTTP_RETURNED_ERROR;
         }
     }while(0);
     
     if(pCurl) curl_easy_cleanup(pCurl);
 ?
     return (nCurlCode==CURLE_OK?0:1);
 }
 ?
 //[处理POST请求:流的行事发出]
 GK8_INT ProcessPostTask(Gk8HttpRequest* pHttpRequest,HTTPWRITE_CALLBACK lpCallBack,GK8_LPVOID lpStream,GK8_LPINT lpResponseCode)
 {
     CURLcode nCurlCode=CURL_LAST;
     CURL* pCurl=curl_easy_init();
 ?
     do
     {
         if(!ConfigureCURL(pCurl)) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_URL,pHttpRequest->GetHttpUrl());
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_WRITEFUNCTION,lpCallBack);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_WRITEDATA,lpStream);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_POST,1);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_POSTFIELDS,pHttpRequest->GetRequestData()->GetBuf());
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_setopt(pCurl,CURLOPT_POSTFIELDSIZE,pHttpRequest->GetRequestDataSize());
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_perform(pCurl);
         if(nCurlCode!=CURLE_OK) break;
 ?
         nCurlCode=curl_easy_getinfo(pCurl,CURLINFO_RESPONSE_CODE,lpResponseCode);
         
         if(nCurlCode!=CURLE_OK||*lpResponseCode!=200)
         {
             nCurlCode=CURLE_HTTP_RETURNED_ERROR;
         }
     }while(0);
     if(pCurl) curl_easy_cleanup(pCurl);
 ?
     return (nCurlCode==CURLE_OK?0:1);
 }
 ?
 //[创建网络线程]
 static GK8_LPVOID NetWorkThread(GK8_LPVOID lpData)
 {
     Gk8HttpRequest* pHttpRequest=NULL;
     Gk8HttpResponse* pHttpResponse=NULL;
 ?
     while(true)
     {
         //Wait for http request tasks from main thread
         GK8_INT nSemWaitRet=sem_wait(sg_pSem);
         if(nSemWaitRet<0)
         {
             _GK8ERR<<"HttpRequest async thread semaphore error:"<<strerror(errno)<<CR;
             break;
         }
 ?
         if(sg_bHttpClientQuit) break;
 ?
         //[第一步:发送HTTP请求]
         pHttpRequest=NULL;
         pthread_mutex_lock(&sg_RequestQueueMutex);
         if(0!=sg_iRequestQueue.GetSize())
         {
             pHttpRequest=sg_iRequestQueue.GetItemAt(0);
             sg_iRequestQueue.RemoveItemAt(0);
         }
         pthread_mutex_unlock(&sg_RequestQueueMutex);
 ?
         if(NULL==pHttpRequest) continue;
 ?
         //[第二步:libCurl同步请求]
         pHttpResponse=new Gk8HttpResponse(pHttpRequest);
 ?
         GK8_INT nResponseCode=-1;
         GK8_INT nRetValue=0;
 ?
         switch(pHttpRequest->GetRequestType())
         {
             case Gk8HttpRequest::kHttpGet:
                 nRetValue=ProcessGetTask(pHttpRequest,WriteHttpData,pHttpResponse->GetResponseData(),&nResponseCode);
                 break;
             case Gk8HttpRequest::kHttpPost:
                 nRetValue=ProcessPostTask(pHttpRequest,WriteHttpData,pHttpResponse->GetResponseData(),&nResponseCode);
                 break;
             default:
                 _GK8ERR<<"Gk8HttpClient:Unkown Request Type,Only GET And POST Are Supported"<<CR;
                 break;
         }
         pHttpResponse->SetResponseCode(nResponseCode);
         //[清除请求中的二进制数据]
         pHttpRequest->ClearRequestData();
 ?
         if(nRetValue!=0)
         {
             pHttpResponse->SetSucceed(false);
             sg_iErrorStr=sg_szErrorBuf;
             pHttpResponse->SetErrorBuffer(sg_iErrorStr);
         }else
         {
             pHttpResponse->SetSucceed(true);
         }
 ?
         pthread_mutex_lock(&sg_ResponseQueueMutex);
         sg_iResponseQueue.AddItem(pHttpResponse);
         pthread_mutex_unlock(&sg_ResponseQueueMutex);
     }
 ?
     sg_AsyncRequestCount-=sg_iRequestQueue.GetSize();
     pthread_mutex_lock(&sg_RequestQueueMutex);
     sg_iRequestQueue.Clear();
     pthread_mutex_unlock(&sg_RequestQueueMutex);
     
     if(sg_pSem!=NULL)
     {
 #if GK8_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE
         sem_unlink(GK8_ASYNC_HTTPREQUEST_SEMAPHORE);
         sem_close(sg_pSem);
 #else
         sem_destroy(sg_pSem);
 #endif
         sg_pSem=NULL;
 ?
         pthread_mutex_destroy(&sg_RequestQueueMutex);
         pthread_mutex_destroy(&sg_ResponseQueueMutex);
 ?
         //[依次删除数据]
         GK8_INT nIndex;
         for(nIndex=0;nIndex<sg_iRequestQueue.GetSize();nIndex++)
         {
             pHttpRequest=sg_iRequestQueue.GetItemAt(nIndex);
             delete pHttpRequest;
         }
         for(nIndex=0;nIndex<sg_iResponseQueue.GetSize();nIndex++)
         {
             pHttpResponse=sg_iResponseQueue.GetItemAt(nIndex);
             delete pHttpResponse;
         }
         sg_iRequestQueue.Destroy();
         sg_iResponseQueue.Destroy();
     }
     pthread_exit(NULL);
     return 0;
 }
 ?
 /////////////////////////////////////////////////////////////////
 Gk8HttpClient::Gk8HttpClient()
 :m_nTimeOutForRead(60)
 ,m_nTimeOutForConnect(30)
 {
 ?
 }
 ?
 Gk8HttpClient::~Gk8HttpClient()
 {
     sg_bHttpClientQuit=true;
     if(sg_pSem!=NULL)
     {
         sem_post(sg_pSem);
     }
 }
 ?
 //[初始化线程]
 GK8_BOOL Gk8HttpClient::InitThreadSemphore()
 {
     if(sg_pSem!=NULL)
     {
         return true;
     }else
     {
 #if GK8_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE
         sg_pSem=sem_open(GK8_ASYNC_HTTPREQUEST_SEMAPHORE,O_CREAT,0644,0);
         if(sg_pSem==SEM_FAILED)
         {
             _GK8ERR<<"Open HttpRequest Semaphore Failed"<<CR;
             sg_pSem=NULL;
             return false;
         }
 #else
         GK8_INT nSemRet=sem_init(&sg_iSem,0,0);
         if(nSemRet<0)
         {
             _GK8ERR<<"Init HttpRequest Semaphore Failed"<<CR;
             return false;
         }
         sg_pSem=&sg_iSem;
 #endif
 ?
         pthread_mutex_init(&sg_RequestQueueMutex,NULL);
         pthread_mutex_init(&sg_ResponseQueueMutex,NULL);
 ?
         pthread_create(&sg_NetWorkThread,NULL,NetWorkThread,NULL);
         pthread_detach(sg_NetWorkThread);
 ?
         sg_bHttpClientQuit=false;
     }
     return true;
 }
 ?
 //[发送HTTP请求]
 GK8_VOID Gk8HttpClient::Send(Gk8HttpRequest* pHttpRequest)
 {
     if(false==InitThreadSemphore()) return;
     if(!pHttpRequest) return;
 ?
     ++sg_AsyncRequestCount;
 ?
     pthread_mutex_lock(&sg_RequestQueueMutex);
     sg_iRequestQueue.AddItem(pHttpRequest);
     pthread_mutex_unlock(&sg_RequestQueueMutex);
 ?
     sem_post(sg_pSem);
 }
 ?
 //[获取HTTP单例]
 Gk8HttpClient* Gk8HttpClient::GetInstance()
 {
     if(sg_pHttpClient==NULL) sg_pHttpClient=new Gk8HttpClient();
     return sg_pHttpClient;
 }
 ?
 //[HTTP响应帧控制]
 GK8_VOID Gk8HttpClient::HttpClientTick()
 {
     if(sg_pSem==NULL) return;
 ?
     Gk8HttpResponse* pHttpResponse=NULL;
 ?
     pthread_mutex_lock(&sg_ResponseQueueMutex);
     if(sg_iResponseQueue.GetSize()>0)
     {
         pHttpResponse=sg_iResponseQueue.GetItemAt(0);
         sg_iResponseQueue.RemoveItemAt(0);
     }
     pthread_mutex_unlock(&sg_ResponseQueueMutex);
     
     if(pHttpResponse)
     {
         --sg_AsyncRequestCount;
         Gk8HttpRequest* pHttpRequest=pHttpResponse->GetHttpRequest();
         Gk8BaseObj* pTarget=pHttpRequest->GetTarget();
         HTTPREQUEST_CALLBACK_FUN pSelector=pHttpRequest->GetSelector();
 ?
         //[回调处理:记录数据]
         if(pTarget&&pSelector)
         {
             (pTarget->*pSelector)(pHttpResponse);
         }
         //[销毁请求数据]
         delete pHttpResponse;
     }
 }

C++实现Servlet类:Gk8HttpServlet.h

 #ifndef __GK8HTTPSERVICE_H__
 #define __GK8HTTPSERVICE_H__
 ?
 #pragma once
 #include "curl/curl.h"
 #include "Gk8HttpClient.h"
 #include "Gk8HttpRequest.h"
 #include "Gk8HttpResponse.h"
 ?
 class Gk8HttpServlet:public Gk8BaseObj
 {
     DECLARE_TOSPP_MAP;
 private:
     Gk8Str m_sHttpUrl;              //[HTTP请求地址]
     Gk8ByteMaker m_iRequestData;    //[HTTP请求数据]
     Gk8Var m_iHttpCallVar;          //[HTTP回调信息]
 ?
     GK8_VOID ServletRequestCompleted(GK8_LPVOID lpHttpResponse);
 public:
     Gk8HttpServlet();
     ~Gk8HttpServlet();
 ?
     GK8_VOID TOSPPFUNC SendHttpMessage(GK8_LPCSTR lpHttpData,Gk8Var& iHttpCallVar);
 };
 #endif

C++实现Servlet类:Gk8HttpServlet.cpp

 #include "Gk8HttpServlet.h"
 #include "Gk8OperSys.h"
 #include "Gk8Helper.h"
 ?
 static Gk8Str sg_iReceiveMessageEvent("OnReceiveMessage");//[接收网络信息]
 ?
 #define HTTPSERVLET_FAIL        0       //[HTTP请求失败]
 #define HTTPSERVLET_SUCC        1       //[HTTP请求成功]
 ?
 /////////////////////////////////////////////CLASS-TOLUA////////////////////////////////////////////////////
 TOLUA_CLASS_COLLECT_FUNC(Gk8HttpServlet)
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8HttpServlet,NewObj)
     if(!CheckToLuaFunParam(L,"NewObj",Gk8Var()<<ISUSERTABLE("Gk8HttpServlet")<<ISVABOOLEAN<<ISNOOBJ)) return 0;
     Gk8HttpServlet* pHttpServlet=(Gk8HttpServlet*)Mtolua_new((Gk8HttpServlet)());
     tolua_pushusertype(L,(GK8_LPVOID)pHttpServlet,"Gk8HttpServlet");
     if(IFBOOLEAN(2)) tolua_register_gc(L,lua_gettop(L));
 END_TOLUA_CLASS_FUNC
 ?
 BEGIN_TOLUA_CLASS_FUNC(Gk8HttpServlet,SendHttpMessage)
     if(!CheckToLuaFunParam(L,"SendHttpMessage",Gk8Var()<<ISUSERTYPE("Gk8HttpServlet")<<ISSTRING<<ISVAFUNCTION<<ISNOOBJ)) return 0;
     //TOLUAGETOBJ(Gk8HttpServlet,1)->SendHttpMessage(TOLUAGETSTRING(2),TOLUAGETFUNEX(L,3,0));
 END_TOLUA_CLASS_FUNC
 ?
 //[启动注册类的全部TOLUA函数]
 BEGIN_TOLUA_FUN_MAP(Gk8HttpServlet)
     TOLUA_CLASS(Gk8HttpServlet,Gk8BaseObj,"[网络类]","[HTTP请求类]")
     TOLUA_CLASS_FUNC(Gk8HttpServlet,NewObj,"[Gk8HttpServlet* NewObj(GK8_BOOL ifLocal=false)?创建Gk8HttpServlet对象]")
     TOLUA_CLASS_FUNC(Gk8HttpServlet,SendHttpMessage,"[GK8_VOID SendHttpMessage(GK8_LPCSTR lpHttpData,iHttpCallVar)?发送HTTP请求,字符串模式]")
 END_TOLUA_FUN_MAP
 ?
 /////////////////////////////////////////////CLASS-TOSPP////////////////////////////////////////////////////
 BEGIN_TOSPP_MAP(Gk8HttpServlet,Gk8BaseObj)
     TOSPP_FUNC(Gk8HttpServlet,SendHttpMessage,' ',"s&v","SendHttpMessage(lpHttpData,iHttpCallVar)")
 END_TOSPP_MAP()
 /////////////////////////////////////////////////////////////////////////////////////////////////
 ?
 Gk8HttpServlet::Gk8HttpServlet()
 {
 ?
 }
 ?
 Gk8HttpServlet::~Gk8HttpServlet()
 {
 ?
 }
 ?
 //[发送HTTP请求注意编码问题]
 GK8_VOID Gk8HttpServlet::SendHttpMessage(GK8_LPCSTR lpHttpData,Gk8Var& iHttpCallVar)
 {
     m_sHttpUrl=lpHttpData;
     //[注册脚本回调消息]
     m_iHttpCallVar=iHttpCallVar;
     Gk8Var iEmptyVar;
     if(m_iHttpCallVar.GetSize()==1 && m_iHttpCallVar[0].IfInt()) SetEvent(sg_iReceiveMessageEvent,m_iHttpCallVar[0],iEmptyVar);
     Gk8HttpRequest* pHttpRequest=new Gk8HttpRequest();
     pHttpRequest->SetRequestType(Gk8HttpRequest::kHttpGet);
     pHttpRequest->SetHttpUrl(m_sHttpUrl);
     pHttpRequest->SetResponseCallBack(this,(HTTPREQUEST_CALLBACK_FUN)&Gk8HttpServlet::ServletRequestCompleted);
     pHttpRequest->SetRequestData(&m_iRequestData);
 ?
     Gk8HttpClient::GetInstance()->Send(pHttpRequest);
 }
 ?
 //[HTTP请求信息回调]
 GK8_VOID Gk8HttpServlet::ServletRequestCompleted(GK8_LPVOID lpHttpResponse)
 {
     Gk8HttpResponse* pHttpResponse=(Gk8HttpResponse*)lpHttpResponse;
     if(!pHttpResponse) return;
 ?
     //[把服务器数据派遣到脚本中]
     GK8_INT nFailCode=HTTPSERVLET_SUCC;
     Gk8Str iResponstStr;
     if(!pHttpResponse->IsSucceed())
     {
         _GK8ERR<<"Gk8HttpServlet Response Failed Error Is "<<pHttpResponse->GetErrorBuffer()<<CR;
         iResponstStr="UnKown Error";
         nFailCode=HTTPSERVLET_FAIL;
     }else
     {
         Gk8ByteMaker* pResponseData=pHttpResponse->GetResponseData();
         iResponstStr.BinToStr(pResponseData->GetBuf(),pResponseData->GetStreamSize());
     }
 ?
     if(m_iHttpCallVar.GetSize()==1)
     {
         RunEventWithArgs(sg_iReceiveMessageEvent,iResponstStr);
     }else
     {
         if(!m_iHttpCallVar[0].IfPtr()||!IfObjPtr(m_iHttpCallVar[0].GetPtr(),m_iHttpCallVar[0].GetPtrId())) return;
 ?
         Gk8Obj* pBindObj=m_iHttpCallVar[0].GetSafePtr();
         Gk8Var iParamVar;
         iParamVar<<nFailCode<<iResponstStr;
         pBindObj->OnCall(m_iHttpCallVar[1],iParamVar);
     }
     //[直接删除本身]
     SafeDeleteObj(this);
 }


相关推荐

Go语言泛型-泛型约束与实践(go1.7泛型)

来源:械说在Go语言中,Go泛型-泛型约束与实践部分主要探讨如何定义和使用泛型约束(Constraints),以及如何在实际开发中利用泛型进行更灵活的编程。以下是详细内容:一、什么是泛型约束?**泛型...

golang总结(golang实战教程)

基础部分Go语言有哪些优势?1简单易学:语法简洁,减少了代码的冗余。高效并发:内置强大的goroutine和channel,使并发编程更加高效且易于管理。内存管理:拥有自动垃圾回收机制,减少内...

Go 官宣:新版 Protobuf API(go pro版本)

原文作者:JoeTsai,DamienNeil和HerbieOng原文链接:https://blog.golang.org/a-new-go-api-for-protocol-buffer...

Golang开发的一些注意事项(一)(golang入门项目)

1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...

golang 托盘菜单应用及打开系统默认浏览器

之前看到一个应用,用go语言编写,说是某某程序的windows图形化客户端,体验一下发现只是一个托盘,然后托盘菜单的控制面板功能直接打开本地浏览器访问程序启动的webserver网页完成gui相关功...

golang标准库每日一库之 io/ioutil

一、核心函数概览函数作用描述替代方案(Go1.16+)ioutil.ReadFile(filename)一次性读取整个文件内容(返回[]byte)os.ReadFileioutil.WriteFi...

文件类型更改器——GoLang 中的 CLI 工具

我是如何为一项琐碎的工作任务创建一个简单的工具的,你也可以上周我开始玩GoLang,它是一种由Google制作的类C编译语言,非常轻量和快速,事实上它经常在Techempower的基准测...

Go (Golang) 中的 Channels 简介(golang channel长度和容量)

这篇文章重点介绍Channels(通道)在Go中的工作方式,以及如何在代码中使用它们。在Go中,Channels是一种编程结构,它允许我们在代码的不同部分之间移动数据,通常来自不同的goro...

Golang引入泛型:Go将Interface「」替换为“Any”

现在Go将拥有泛型:Go将Interface{}替换为“Any”,这是一个类型别名:typeany=interface{}这会引入了泛型作好准备,实际上,带有泛型的Go1.18Beta...

一文带你看懂Golang最新特性(golang2.0特性)

作者:腾讯PCG代码委员会经过十余年的迭代,Go语言逐渐成为云计算时代主流的编程语言。下到云计算基础设施,上到微服务,越来越多的流行产品使用Go语言编写。可见其影响力已经非常强大。一、Go语言发展历史...

Go 每日一库之 java 转 go 遇到 Apollo?让 agollo 来平滑迁移

以下文章来源于GoOfficialBlog,作者GoOfficialBlogIntroductionagollo是Apollo的Golang客户端Apollo(阿波罗)是携程框架部门研...

Golang使用grpc详解(golang gcc)

gRPC是Google开源的一种高性能、跨语言的远程过程调用(RPC)框架,它使用ProtocolBuffers作为序列化工具,支持多种编程语言,如C++,Java,Python,Go等。gR...

Etcd服务注册与发现封装实现--golang

服务注册register.gopackageregisterimport("fmt""time"etcd3"github.com/cor...

Golang:将日志以Json格式输出到Kafka

在上一篇文章中我实现了一个支持Debug、Info、Error等多个级别的日志库,并将日志写到了磁盘文件中,代码比较简单,适合练手。有兴趣的可以通过这个链接前往:https://github.com/...

如何从 PHP 过渡到 Golang?(php转golang)

我是PHP开发者,转Go两个月了吧,记录一下使用Golang怎么一步步开发新项目。本着有坑填坑,有错改错的宗旨,从零开始,开始学习。因为我司没有专门的Golang大牛,所以我也只能一步步自己去...