高并发服务器的设计--fastcgi的设计

服务器开发中不何或缺的要使用fastcgi,其使用方法如下:

while( FCGI_Accept() >= 0 ){
                printf( "Content-type: text/plain \r\n"
                "Content-Length: %d\r\n"
                "Connection: close\r\n\r\n%s\r\n", strlen( buffer ), buffer );
        }


facgcgi 头文件有如下宏:

#undef  fprintf
#define	fprintf  FCGI_fprintf
#undef  printf
#define	printf   FCGI_printf

可以看出,已经对printf函数进行了宏转向,在程序里的printf 不再是标准输出了。这样就有一个问题,如果想调试打印信息到stdout中,就不行了。

现实开发中,可能会出现各种问题,有时候的确需要打印出一些信息,这时候可以修改fcgi_stdio.h头文件,改成如下:

#undef  _fprintf
#define _fprintf  FCGI_fprintf
#undef  _printf
#define	_printf   FCGI_printf

在程序中的相应地方也要换成相应的宏。


fastcgi 的解析可以通过这个函数:

char *getenv(const char *name) 

有如下几类参数:

CONTENT_TYPE

CONTENT_TYPE得到请求类型
CONTENT_LENGTH正文段长度
QUERY_STRING请求字串

以如下一段HTTP请求报文为例:

GET /s?ie=utf-8&bs=%E8%BF%99%E6%98%AF&f=8&rsv_bp=1&rsv_spt=3&wd=%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BC%80%E5%8F%91&rsv_sug3=11&rsv_sug=0&rsv_sug4=609&rsv_sug1=2&inputT=32681 HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Referer: http://www.baidu.com/s?wd=%E8%BF%99%E6%98%AF&rsv_bp=0&ch=&tn=baidu&bar=&rsv_spt=3&ie=utf-8&rsv_sug3=4&rsv_sug=0&rsv_sug4=240&rsv_sug1=3&inputT=2835
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: BAIDUID=A83324E58AE26486E46FC49ED127891B:FG=1; BDSVRTM=163; H_PS_PSSID=1439_2448_2454_2256_1788_2249; WWW_ST=1369271667063

CONTENT_TYPE 对应第5行,QUERY_STRING 对应第一行。


fastcgi 不是面向对象的,所有的任务都是在主循环内完成,包括解析,处理,响应。

在实际的开发中,为了提高效率,开发成员不用关心底层,我将其封装成一个类:fcgi_net_duty

#ifndef __FCGI_NET_H__
#define __FCGI_NET_H__

#define FCGI_NET_OK           0
#define FCGI_NET_ERROR        1
#define FCGI_NET_PARAM_ERROR  2

enum fcgi_net_type
{
        FCGI_NET_TEXT = 0,
        FCGI_NET_APP_STREAM,
        FCGI_NET_IMAGE,
};

class fcgi_net_duty
{
public:
        fcgi_net_duty();
        ~fcgi_net_duty();

        void do_request();

protected:
        void  do_prev();
        void  do_cast();
        virtual void  do_handle();
        void  do_write();
        void  do_finish();

        int get_req_int( const char* param, int *value );        
        int get_req_ll( const char* param, long long *value );
        int get_req_str( const char* param, const char **value );

        int get_cookie_int( const char* param, int *value );
        int get_cookie_ll( const char* param, long long *value );
        int get_cookie_str( const char* param, const char **value );


private:
        std::map< const char*, const char* > m_req;
        std::map< const char*, const char* > m_cookie;

        int rtn;        
        int content_type;
        int content_length;
        char* content_buf;

};



主循环放在do_request 函数里

fcgi_net_duty.cpp

void fcgi_net_duty::do_request()
{
        while( FCGI_Accept() >= 0 ){
                do_prev();
                do_cast();
                do_handle();
                do_write();
                do_finish();
        }
}

子类只需要关心相应的业务,每个业务可以用一个子类完成,如现有三个业务:busi1, busi2, busi3,我们以其中一个为例:

fcig_busi1.h

#ifndef __FCGI_BUSI1_H__
#define __FCGI_BUSI1_H__

class fcgi_busi1 : public fcgi_net_duty
{
public: 
        fcgi_busi1();
        ~fcgi_busi1();

        void do_handle();

};


#endif //__FCGI_BUSI1_H__


fcgi_busi1.cpp
void fcgi_busi1::do_handle()
{
        const char* busi1;
        int flag;

        rtn = FCGI_NET_ERROR;

        flag = get_req_str( "busi1", &busi1 );
        if( flag ){
                rtn = FCGI_NET_PARAM_ERROR;
                return;
        }

        sprintf( content_buf, "%s","your busi is ok" );
        rtn = FCGI_NET_OK;

}

int main()
{
        fcgi_busi1 busi1;
        busi1.do_request();
}

相应的makefile:

INC=-I./ 
LIB=-L/usr/lib64 -lfcgi

CPPFLAGS=-g -w $(INC)
CC=g++

BUSI1=./build/busi1
BUSI2=./build/busi2
BUSI3=./build/busi3

all: $(BUSI1) $(BUSI2) $(BUSI3)

$(BUSI1): ./fcgi_net_duty.o ./fcgi_busi1.o
        $(CC) -O $@ $^ $(LIB)

$(BUSI2): ./fcgi_net_duty.o ./fcgi_busi2.o
        $(CC) -O $@ $^ $(LIB)

$(BUSI3): ./fcgi_net_duty.o ./fcgi_busi3.o
        $(CC) -O $@ $^ $(LIB)

OK,现在一个轻型的fastcgi开发框架就搭建起来了,现实开发中,可以让一个成员开发网络处理,其他人专门做相应的业务处理,可以达到事半功倍的处理,我的理念就是让专业的人做专业的事,这样大家在专业技能上有更好的提升。




  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值