BREW是无线二进制运行环境(Binary Runtime Environment for Wireless)的缩写, 是高通公司2001年推出的基于CDMA网络 "无线互联网发射平台" 上增值业务开发运行的基本平台。它提供一个高效、低成本、可扩展和熟悉的应用程序执行环境(AEE), 着重开发可无缝植入任何实际手持设备的应用程序。BREW主要应用在移动通信领域,BREW类似一个开放免费的PC操作系统。
在BREW平台上的网络应用主要是IScoket和IWeb接口,IWeb使用更简单、方便些。在BREW下应用IWeb接口,主要过程如下:
1.初始化接口:一般把这部分代码放在了App_InitAppData函数中
if (ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_WEB, (void **)&pMe->pIWeb) != SUCCESS)
{
pMe->pIWeb = NULL;
return TRUE;
}
else
{ // 3a. Set up the callback function to receive response from server
CALLBACK_Init(&pMe->WebCBStruct, IWebCB, pMe); // out, in, in
}
if (SUCCESS != ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_FILEMGR, (void **)&pMe->pfm))
{
IAPPLET_Release((IApplet*)pMe);
return TRUE;
}
if (SUCCESS != ISHELL_CreateInstance(pMe->a.m_pIShell,AEECLSID_WEBUTIL,(void **)&pMe->pIWebUtil))
{
pMe->pIWebUtil = NULL;
return TRUE;
}
//初始化回调
CALLBACK_Init(&pMe->WebCBStruct, IWebCB, pMe); // out, in, in
//IWebCB函数定义
void IWebCB (iweb* pMe) {
// get info about the response
pMe->pWebRespInfo = IWEBRESP_GetInfo(pMe->pIWebResp);
// 5.a check error code
if (!WEB_ERROR_SUCCEEDED(pMe->pWebRespInfo->nCode))
{
return;
}
// 5.b get pointer to Source object
pMe->pISource = pMe->pWebRespInfo->pisMessage;
if (pMe->pISource == NULL)
{
return;
}
// 5.c register Isource Read callback
CALLBACK_Init(&pMe->WebCBStruct, ReadFromWebCB, pMe); // out, in, in
// 5.d post a read; data is processed by ISource callback
ISOURCE_Readable(pMe->pISource, &pMe->WebCBStruct);
return;
}
void ReadFromWebCB(iweb* pMe)
{
AECHAR szText[] = {'D','o','w','n','l','o','a','d', ' ','F', 'i', 'n', 'i','s','h','\0'};
char buf[1024]; // allocate buffer
int byteCount;
// read data from stream; get number of bytes read
byteCount = ISOURCE_Read(pMe->pISource, (char*)buf, sizeof(buf));
switch (byteCount) {
case ISOURCE_WAIT: // Buffer empty, but more data expected // post another read
ISOURCE_Readable(pMe->pISource,&pMe->WebCBStruct);
return;
case ISOURCE_ERROR: // Error occurred ProcessError(…);
case ISOURCE_END: // Buffer empty; all data received ProcessData(…);
IDISPLAY_DrawText(pMe->a.m_pIDisplay, // Display instance
AEE_FONT_BOLD, // Use BOLD font
szText, // Text - Normally comes from resource
-1, // -1 = Use full string length
0, // Ignored - IDF_ALIGN_CENTER
0, // Ignored - IDF_ALIGN_MIDDLE
NULL, // No clipping
IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE);
IDISPLAY_Update(pMe->a.m_pIDisplay);
return;
default: // data read; copy from chunk buffer
IFILE_Write(pMe->pIFile,buf,byteCount);
// post another read
ISOURCE_Readable(pMe->pISource,&pMe->WebCBStruct);
return;
}
}
//http请求头的设置
{
int i = 0;
WebOpt awo[10];
// set the IWeb connect timeout to 10 seconds. this also sets the
// failover timeout, if unset, or set to 0, IWeb uses the system
// default (30 seconds unless an OEM changes it)
awo[i].nId = WEBOPT_CONNECTTIMEOUT;
awo[i].pVal = (void *)100000;
i++;
// test user-agent, uncomment this section to ship your own user-agent
// string. if unset, IWeb will send a default. If set to NULL, no
// user agent header will be sent */
// Set TEST_USER_AGENT in the NetDiagnostics project settings to all
// shipping of your own user agent.
#ifdef TEST_USER_AGENT
awo[i].nId = WEBOPT_USERAGENT;
awo[i].pVal = (void *)WEBBER_USERAGENT;
i++;
#endif
// test nowaitconn, this only comes into effect if you build webber
// with multiple WebActions (see the definition of struct Webber)
awo[i].nId = WEBOPT_FLAGS;
awo[i].pVal = (void *)WEBREQUEST_NOWAITCONN;
i++;
// test forcenew, uncomment this section to try multiple simultaneous
// "forced" new connections. Forced new connections are not kept alive
// unless they are the first forced new connection to a host
#ifdef TEST_FORCENEWCONN
awo[i].nId = WEBOPT_FLAGS;
awo[i].pVal = (void *)WEBREQUEST_FORCENEWCONN;
i++;
#endif
// turn off HTTP over HTTP proxying
awo[i].nId = WEBOPT_PROXYSPEC;
awo[i].pVal = (void *)"http:///";
i++;
// turn on ALL proxying. Proxyspecs are examined in WebOpt
// order, so in this list, with the above and below PROXYSPECs,
// everything except HTTP will be proxied through
// http://webproxy.yourdomain.com:8080, (which you'll have to
// set up to test, sorry
awo[i].nId = WEBOPT_PROXYSPEC;
awo[i].pVal = (void *)"*:///http://192.168.1.46:80";
i++;
// Marks the end of the array of WebOpts
awo[i].nId = WEBOPT_END;
// Add Options
IWEB_AddOpt(pApp->m_pIWeb,awo);
}
// Initialize all my WebActions to point to applet
FOR_ALL_WEBACTIONS(pApp, p, p->pParent = pApp);
//打开或建立接收响应数据的文件
pMe->pIFile = IFILEMGR_OpenFile(pMe->pfm, "Rev.txt", _OFM_READWRITE);
if (NULL == pMe->pIFile)
{
pMe->pIFile = IFILEMGR_OpenFile(pMe->pfm, "Rev.txt", _OFM_CREATE);
if (NULL == pMe->pIFile)
{
int Result = GETLASTFPERROR();
return FALSE;
}
}
2.发送请求:其响应消息在回调函数ReadFromWebCB中接收,IWeb状态、
IWEB_GetResponse(pMe->pIWeb,
(pMe->pIWeb,
&pMe->pIWebResp,
&pMe->WebCBStruct,
m_gOutURL,
//WEBOPT_HEADER,"GET /vt/v=w2.119&hl=zh-CN&gl=cn&x=53399&y=28435&z=16&s=Gali HTTP/1.0\r\nAccept:*/*\r\nX-Method:GET\r\nHost:203.208.37.99",
WEBOPT_HEADERHANDLER, WebAction_Header,
WEBOPT_STATUSHANDLER, WebAction_Status,
WEBOPT_END))
这里也可以直接设置这个请求头(WEBOPT_HEADER)、请求消息(WEBOPT_BODY),如上所示。Method默认的就是GET,
WEBOPT_STATUSHANDLER表示后面的WebAction_Status回调函数(功能是IWeb状态)、WEBOPT_HEADERHANDLER的用法和
上面的WEBOPT_STATUSHANDLER的用法一样,后面跟的是服务端返回消息的回调函数,如下所示。
//IWeb 状态
static void WebAction_Status(void *p, WebStatus ws, void *pVal)
{
char *pszStatus = NULL;
switch (ws) {
case WEBS_CANCELLED:
//ISHELL_LoadResString(pApp->a.m_pIShell,"MessageBox",IDC_CANCEL,pApp->m_AnimalTitle,sizeof(pApp->m_AnimalTitle));
pszStatus = "** cancelled...\n";
break;
case WEBS_GETHOSTBYNAME:
//ISHELL_LoadResString(pApp->a.m_pIShell,"MessageBox",IDC_FIND_HOST,pApp->m_AnimalTitle,sizeof(pApp->m_AnimalTitle));
pszStatus = "** finding host...\n";
break;
case WEBS_CONNECT:
pszStatus = "** connecting...\n";
//ISHELL_LoadResString(pApp->a.m_pIShell,"MessageBox",IDC_CONNECTING,pApp->m_AnimalTitle,sizeof(pApp->m_AnimalTitle));
break;
case WEBS_SENDREQUEST:
pszStatus = "** sending...\n";
//ISHELL_LoadResString(pApp->a.m_pIShell,"MessageBox",IDC_SEND,pApp->m_AnimalTitle,sizeof(pApp->m_AnimalTitle));
break;
case WEBS_READRESPONSE:
pszStatus = "** receiving...\n";
//ISHELL_LoadResString(pApp->a.m_pIShell,"MessageBox",IDC_RECEIVE,pApp->m_AnimalTitle,sizeof(pApp->m_AnimalTitle));
break;
case WEBS_GOTREDIRECT:
//pszStatus = "** redirect...\n";
break;
case WEBS_CACHEHIT:
pszStatus = "** cache hit...\n";
break;
}
}
//返回信息头
static void WebAction_Header(void *p, const char *cpszName, GetLine *pglVal)
{
WebAction *pwa = (WebAction *)p;
CDBApp * pApp = pwa->pParent;
if ((char *)0 != cpszName) {
// ND_Print(pApp, "%s:", cpszName);
;
}
//ND_Print(pApp, "%s\n", pglVal->psz);
}