PHP中的FastCGI初識

FastCGI初始:

http://www.cnblogs.com/JohnABC/p/3529786.html



PHP中fastcgi的實現:


1、開啓一個socket監聽服務

    fcgi_fd=fcgi_listen();

    完成socket、bind、listen三步


2、初始化請求對象

    fcgi_init_request(&request,fcgi_fd);

    struct fcgi_request{

        int listen_socket;

        int fd,

        int id;

        int keep;

        int closed;

        

        int in_len;

        int in_pad;


        HashTable* env;

    };


3、創建多個CGI解釋器子進程

    這裏子進程的個數默認是0,從配置文件中讀取設置到環境變量,然後在程序中讀取,然後創建指定數目的子進程來等待處理 Web 服務器的請求。


4、在子進程中接收請求

    fcgi_accept_request(&request);

    並且把request放入全局變量sapi_globals.server_context,這點很重要,方便了在其他地方對請求的調用。


5、讀取數據

    fcgi_read_request(fcgi_request* req);


6、執行腳本


7、結束請求

    fcgi_finish_requests(&request,1);



消息頭

    對於fastcgi這種數據收發協議來說,它所發送的每次請求或是回覆都有一個可提取的公共部分就是FCGI_Header(請求頭),及不管每次發送的是什麼消息,都必須會有一個如下格式的請求頭


typedef struct {    

   unsigned char version;              //版本    unsigned char type;                 //操作類型    unsigned char requestIdB1;          //請求id    unsigned char requestIdB0;              unsigned char contentLengthB1;      //內容長度    unsigned char contentLengthB0;    

   unsigned char paddingLength;        //填充字節的長度    unsigned char reserved;             //保留字節

}FCGI_Header;


消息體

1、type爲1

開始請求

typedef struct {    

   unsigned char roleB1;       //web服務器所期望php-fpm扮演的角色,具體取值下面有    unsigned char roleB0;    

   unsigned char flags;        //確定php-fpm處理完一次請求之後是否關閉    unsigned char reserved[5];  //保留字段

}FCGI_BeginRequestBody;

roleB0=1    是最常用的值,php-fpm接受我們的http所關聯的信息,併產生個響應

flags            確定是否與php-fpm建立長連接,爲1長連接,爲0則在每次請求處理結束之後關閉連接 

2、type爲3

結束請求

typedef struct {    

   unsigned char appStatusB3;      //結束狀態,0爲正常    unsigned char appStatusB2;    

   unsigned char appStatusB1;    

   unsigned char appStatusB0;    

   unsigned char protocolStatus;   //協議狀態    unsigned char reserved[3]; }FCGI_EndRequestBody;

appStatus                 共4個字節,用來表示結束狀態,0爲正常結束 

protocolStatus        爲協議所處的狀態,0爲正常狀態 

3、type爲4

typedef struct {    

   unsigned char nameLengthB3; /* nameLengthB0 >> 7 == 0 */    unsigned char nameLengthB2;    

   unsigned char nameLengthB1;    

   unsigned char nameLengthB0;    

   unsigned char valueLengthB3; /* nameLengthB0 >> 7 == 0 */    unsigned char valueLengthB2;    

    unsigned char valueLengthB1;    

   unsigned char valueLengthB0;    

   unsigned char nameData[(B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0];    

   unsigned char valueData[valueLength((B3 & 0x7f) << 24) + (B2 << 16) + (B1 << 8) + B0]; } FCGI_NameValue;

nameLength    佔用4字節,用來說明name的長度 

valueLength    4個字節,用來說明value的長度

前8個字節之後緊跟的爲nameLength長度的name值,接着是valueLength長度的value值

4、type值爲5,6,7

當消息爲輸入,輸出,錯誤時,它的消息頭之後便直接跟具體數據

完整消息record

fastcgi將一個完整的消息稱爲record,我們每次發送的單位就是record。通過上面的介紹,我們可以總結出常見的記錄格式

type值record
1header(消息頭) + 開始請求體(8字節)
3header + 結束請求體(8字節)
4header + name-value長度(8字節) + 具體的name-value
5,6,7header + 具體內容


http://ms.csdn.net/share/5EB5472B0837D27DEB083BA97982ED2F_1_IPHONE_APP

http://blog.csdn.net/Shreck66/article/details/50355729


《完》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章