FastCGI无需库即可处理多个请求

时间:2019-01-14 14:49:20

标签: fastcgi

我想知道如何使用一个程序实例处理多个请求,这就是说,一个fcgi程序应该在一个请求得到响应后继续运行,问题是,我怎么知道环境变量中的当前请求数据不是最后一个请求中的数据。

我的想法是在解析后使用setenv将环境变量设置为NULL,因此当它们不是NULL时,这意味着服务器已将它们设置为环境变量的值。新请求,但是我不确定这是否应该完成。

我知道有一些可以处理这些内容的库,使用它们更安全,但是现在我的目标只是学习fcgi在库后面的工作方式

1 个答案:

答案 0 :(得分:0)

不清楚您的问题中“多次请求”是什么意思。

根据您的描述,我认为您希望您的FastCgi应用程序在处理完第一个请求后仍然有效,并且可以处理另一个请求。 但这就是FastCgi的本质:单个程序/服务正在“无限循环”中运行并处理所有传入的请求。 FastCGI设计保证可以正确设置Request对象(包括所有环境变量)。

旧的CGI以相反的方式工作:每次请求都会产生CGI程序的新进程(即实例)。

您极有可能热衷于并发请求。但这仍然是可能的。 不幸的是,您没有提到服务器类型,编程语言或使用的操作系统。

在C / C ++中的Unix系统上查找处理并发请求的示例非常容易。

您已经提到过,您不想使用任何库,但是我相信您必须至少使用一个实现FastCGI接口的库。最常用的是Open Market的fcgiapp。 处理并发请求是通过称为锁的多线程技术实现的。 我是“ Windows专家”,所以这是我的WINAPI和C示例:

#define THREAD_COUNT 20
#define FAST_CGI_SOCKET ":9345"

#include <locale.h>
#include "fcgiapp.h"

CRITICAL_SECTION accept_mutex;

DWORD WINAPI requestHandler()
{
    int code;
    FCGX_Request request;
    FCGX_InitRequest(&request, 0, 0);

    for (;;)
    {
        EnterCriticalSection(&accept_mutex);
        code = FCGX_Accept_r(&request);
        LeaveCriticalSection(&accept_mutex);    

        if (code < 0) break;

        // TODO handle request

        FCGX_Finish_r(&request);
    }

    return 0;
}

void initFastCgi() {
    FCGX_Init();
    FCGX_OpenSocket(FAST_CGI_SOCKET, SOMAXCONN);
}

void startThreadsAndWait() {
    int i;
    HANDLE threads[THREAD_COUNT];

    InitializeCriticalSection(&accept_mutex);    

    for (i = 0; i < THREAD_COUNT; i++) {
        threads[i] = CreateThread(NULL, 0, &requestHandler, NULL, 0, NULL);
    }

    for (i = 0; i < THREAD_COUNT; i++) {
        WaitForSingleObject(threads[i], INFINITE);
    }

    for (i = 0; i < THREAD_COUNT; i++) {
        CloseHandle(threads[i]);
    }
}

void appStart() {
    setlocale(LC_ALL, "en_US.utf8");

    initFastCgi();
}

void freeResources() {

}

void appFinish() {
    freeResources();
}

int main(void)
{
    appStart();
    startThreadsAndWait();
    appFinish();

    return 0;
}

所有魔力都围绕在accept_mutex上。

希望即使您使用其他操作系统或编程语言也有帮助