優秀的輕量級網路開發架構spserver源碼分析(一)

來源:互聯網
上載者:User

1。架構介紹

http://iunknown.javaeye.com/blog/59804

 

2。源碼分析

下文源碼分析基於最新源碼0.9.5,http://code.google.com/p/spserver/downloads/list

 

3。主程式

SP_Server的調用鏈條是runForever()->eventLoop()->start()

start()中有如下方法

  acceptArg.mEventArg = &eventArg;
  acceptArg.mHandlerFactory = mHandlerFactory;
  acceptArg.mIOChannelFactory = mIOChannelFactory;
  acceptArg.mReqQueueSize = mReqQueueSize;
  acceptArg.mMaxConnections = mMaxConnections;
  acceptArg.mRefusedMsg = mRefusedMsg;

  struct event evAccept;
  event_set( &evAccept, listenFD, EV_READ|EV_PERSIST,
    SP_EventCallback::onAccept, &acceptArg );
  event_base_set( eventArg.getEventBase(), &evAccept );
  event_add( &evAccept, NULL );

結合libevent我們可以看出,這裡是將伺服器的socket(listenFD)和EV_READ事件註冊到libevent當中

當有用戶端連入時,去找SP_EventCallback::onAccept去處理

 

轉入到SP_EventCallback::onAccept 當中,可以注意到如下關鍵代碼

void SP_EventCallback :: onAccept( int fd, short events, void * arg )
{
    int clientFD;
    struct sockaddr_in addr;
    socklen_t addrLen = sizeof( addr );

    SP_AcceptArg_t * acceptArg = (SP_AcceptArg_t*)arg;
    SP_EventArg * eventArg = acceptArg->mEventArg;

    clientFD = accept( fd, (struct sockaddr *)&addr, &addrLen );
    if( -1 == clientFD ) {
        sp_syslog( LOG_WARNING, "accept failed" );
        return;
    }

    if( SP_IOUtils::setNonblock( clientFD ) < 0 ) {
        sp_syslog( LOG_WARNING, "failed to set client socket non-blocking" );
    }

    SP_Sid_t sid;
    sid.mKey = eventArg->getSessionManager()->allocKey( &sid.mSeq );
    assert( sid.mKey > 0 );

    SP_Session * session = new SP_Session( sid );

    char strip[ 32 ] = { 0 };
    SP_IOUtils::inetNtoa( &( addr.sin_addr ), strip, sizeof( strip ) );
    session->getRequest()->setClientIP( strip );
    session->getRequest()->setClientPort( ntohs( addr.sin_port ) );

    if( 0 == getsockname( clientFD, (struct sockaddr*)&addr, &addrLen ) ) {
        SP_IOUtils::inetNtoa( &( addr.sin_addr ), strip, sizeof( strip ) );
        session->getRequest()->setServerIP( strip );
    }

    if( NULL != session ) {
        eventArg->getSessionManager()->put( sid.mKey, sid.mSeq, session );

        session->setHandler( acceptArg->mHandlerFactory->create() );
        session->setIOChannel( acceptArg->mIOChannelFactory->create() );
        session->setArg( eventArg );

        event_set( session->getReadEvent(), clientFD, EV_READ, onRead, session );
        event_set( session->getWriteEvent(), clientFD, EV_WRITE, onWrite, session );

        if( eventArg->getSessionManager()->getCount() > acceptArg->mMaxConnections
                || eventArg->getInputResultQueue()->getLength() >= acceptArg->mReqQueueSize ) {
            sp_syslog( LOG_WARNING, "System busy, session.count %d [%d], queue.length %d [%d]",
                eventArg->getSessionManager()->getCount(), acceptArg->mMaxConnections,
                eventArg->getInputResultQueue()->getLength(), acceptArg->mReqQueueSize );

            SP_Message * msg = new SP_Message();
            msg->getMsg()->append( acceptArg->mRefusedMsg );
            msg->getMsg()->append( "/r/n" );
            session->getOutList()->append( msg );
            session->setStatus( SP_Session::eExit );

            addEvent( session, EV_WRITE, clientFD );
        } else {
            SP_EventHelper::doStart( session );
        }
    } else {
        eventArg->getSessionManager()->remove( sid.mKey, sid.mSeq );
        sp_close( clientFD );
        sp_syslog( LOG_WARNING, "Out of memory, cannot allocate session object!" );
    }
}

有上述分析,可以看到accept收到了clientFD,然後建立session,由event_set對clientFD和session進行封裝,當clientFD產生EV_READ(有資料傳入伺服器)時調用onRead,當clientFD產生EV_WRITE(資料可以發送)調用onWrite.

.....未完待續

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.