首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Symbian >

向Symbian老手们请问一个有关问题

2012-12-15 
向Symbian老手们请教一个问题在模拟器上出现的问题是:在局域网通畅,外网断网的情况下,向外网发送http请求,

向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呢?
[其他解释]
该问题出现的概率较小,一般在地铁或者不经意的时候“非常偶尔”地出现。公司产品部门要求比须解决。
[其他解释]

引用:
你的提交操作是怎么执行的?在定时器中执行http队列,进行提交会有改善。另外可以把提交操作移至独立线程里。



void NetworkEngine::HttpRequestGet( const TDesC8 & aUri, TInt aRang, TInt aGetDataLength )
{
    CancelHttpRequest();
    TUriParser8 uri;
    uri.Parse( aUri );
    iLastUrl.AssginData( aUri );
    //if ( !iIsConnected )
    {
        if ( !iIapEngine->SetupConnectionL( iSession ) )
        {
            if ( iMHttpObserver )
            {


                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阻塞问题,后改用定时器处理得到改善,至今再没发现有类似问题。

热点排行