向Symbian老手们请教一个问题
在模拟器上出现的问题是:在局域网通畅,外网断网的情况下,向外网发送http请求,提交请求后,出现了短暂的死机现象.向局域网发出的http请求都是有响应的,并且没有死机现象。
具体是:
执行(1) iNetEngine->HttpRequestGet(_L("http://a.uuarea.com/v.do?pageID=10885"),0); 向外网发出post请求出现死机。
执行(2) iNetEngine->HttpRequestGet(_L("http://172.16.0.1/"firstConnect_3pingan.html?lid=0&st=1"),0); 想内网发出post请求正常。
出现这个问题的环境是:(3)外网的服务器网线断了,不通,内网通。
之所以提出这个问题是因为在手机上面测试发现,执行(1)时小概率出现几秒钟的死机现象,此时定时器无法刷屏幕滚动文字、也不能响应按键,过几秒钟就好了。但是在模拟器里面不会出现这种现象,除非出现了现象(3)。
语句(1)是为了得到手机号码。connection是连接上了的。现象出现在 iTransaction.SubmitL( ); 后。
请老手高手们给些参考意见,不胜感激。
[最优解释]
symbian初学者。。。友情帮顶。
[其他解释]
你的提交操作是怎么执行的?在定时器中执行http队列,进行提交会有改善。另外可以把提交操作移至独立线程里。
[其他解释]
我的是在http请求前的连接GPRS时会有几秒钟假死机情况,这个是必现的,第一次连接完成后就再没出现过,这是真机的。
模拟器经常出现假死机现象。
[其他解释]
aGetDataLength > 0 )
{
TBuf8 < 64 > rangeBuf;
rangeBuf.Append( _L8( "bytes=" ) );
rangeBuf.AppendNum( aRang );
rangeBuf.Append( _L8( "-" ) );
rangeBuf.AppendNum( aRang + aGetDataLength - 1 );
SetHeaderL( hdr, HTTP::ERange, rangeBuf );
}
//DumpHeadersL(hdr);
// Submit the transaction. After this the framework will give transaction
// events via MHFRunL and MHFRunError.
//iFramework->SetUpdateRate( CSYMFramework::EUpdateLow );
iTransaction.SubmitL( );
iRunning = ETrue;
}
HttpRequestGet()函数执行完后出现了短暂的死机,然后才到MHFRunL,aEvent.iStatus是负数。
[其他解释]
因为http请求非常频繁,暂未使用线程。
RConnection类的实例对象不能够进行跨线程调用
理论上讲,RHTTPTransaction是异步操作,系统会起线程啊。为什么还会阻塞UI呢?
[其他解释]
该问题出现的概率较小,一般在地铁或者不经意的时候“非常偶尔”地出现。公司产品部门要求比须解决。
[其他解释]
iMHttpObserver->HttpClientEvent( -1 );
}
return;
}
}
iRecvData.ClearData();
// Get request method string for HTTP GET
RStringF method = iSession.StringPool( ).StringF( HTTP::EGET, RHTTPSession::GetTable( ) );
// Open transaction with previous method and parsed uri. This class will
// receive transaction events in MHFRunL and MHFRunError.
iTransaction = iSession.OpenTransactionL( uri, *this, method );
// Set headers for request; user agent and accepted content type
RHTTPHeaders hdr = iTransaction.Request( ).GetHeaderCollection( );
//SetHeadersL( hdr, iHeaderString.Des() );
SetHeaderL( hdr, HTTP::EUserAgent, iIapEngine->GetUserAgent() );
SetHeaderL( hdr, HTTP::EAccept, KAccept );
if ( aRang > 0
[其他解释]
你给出的这个是具体的请求函数。我的意思是,在需要执行网路请求的地方不要直接调用这个函数,而是先放入请求队列,然后通知队请求管理器(比如:启动一个定时器)来执行该请求。
[其他解释]
我目前的处理是一次只是提交一个http请求,一个请求处理完了才提交第二个请求,像这种情况下使用定时器会有改善么?还是必须用线程呢?
[其他解释]
根据你的修改意见,我做了如下的调整:
在活动对象中拨号(还是做3次尝试):
TBool IapEngine::SetupConnectionL( RHTTPSession aSession, TAny *aPtr )
{
if ( IsActive() ) { Cancel(); }
。。。
iConnection.Start( connectPref, iStatus );
SetActive();
}
void IapEngine::RunL()
{
if(iStatus.Int()== KErrNone)
{
iConnectCount=0;
SessionConnect( iSession );
if ( isDialog )
{
iSelectedIap = connectPref.IapId();
}
iConnectionSetupDone = ETrue;
if ( !iSetWapConnect&&iSelectedIap!=0xff )
{
SaveIap( iIapSavePath, iSelectedIap );
}
((NetworkEngine*)iPtr)->DoHttpRequest(KErrNone);
}
else
{
if(iConnectCount>=3)
{
iConnectCount=0;
((NetworkEngine*)iPtr)->DoHttpRequest(aError);
}
else
{
iSelectedIap = 0xff;
iConnectionSetupDone = EFalse;
SetupConnectionL(iSession, iPtr);
}
}
}
在定时器中提交请求:
void NetworkEngine::DoHttpRequest(TInt aErrCode/* = KErrNone*/)
{
if ( aErrCode != KErrNone )
{
if ( iMHttpObserver )
{
iMHttpObserver->HttpClientEvent( -1 );
}
return;
}
iRecvData.ClearData();
TUriParser8 uri;
uri.Parse( iLastUrl.Des() );
if (iLastPostbuffer.Des().Length() <= 0) //get
{
。。。
}
else //post
{
。。。
}
iScheduler->Cancel();
iScheduler->Start(100000, 100000, TCallBack(OnSchedule, this));
}
TInt NetworkEngine::OnSchedule(TAny* aObject)
{
NetworkEngine *inst = (NetworkEngine*)aObject;
if(NULL == inst) { return KErrNotReady; }
static_cast<NetworkEngine*>(aObject)->DoSubmitL();
return KErrNone;
}
void NetworkEngine::DoSubmitL()
{
iScheduler->Cancel();
iTransaction.SubmitL();
iRunning = ETrue;
}
不过,对于 “在定时器中执行http队列,进行提交会有改善。”我始终还是持怀疑态度。
[其他解释]
网络不通提交本身不可能被解决,但至少UI不会被阻塞。早前曾碰到过UI阻塞问题,后改用定时器处理得到改善,至今再没发现有类似问题。