1.lighttpd 服务器
lighttpd是一个比较轻量的服务器,在运行fastcgi上效率较高。lighttpd只负责投递请求到fastcgi。
centos输入yum install lighttpd安装
2.fastcgi
fastcgi解决了cgi程序处理请求每次都要初始化和结束造成的性能问题。fastcgi并且是独立于webserver的,fastcgi的crash并不影响webserver,然后他们之间通过soket通信。与fastcgi不同的另一种解决cgi程序反复创建,销毁的方法是让webserver开放api,然后编写cgi的时候,把cgi嵌入到webserver中,这样有个不好的地方就是cgi的crash会影响到webserver。
支持fastcgi的服务器有很多比如,nginx
IIS什么的。他们都是把http请求转换为stdin和一些环境变量传递给fastcgi程序,然后返回stdout。编写fastcgi程序最终要的一个api就是int
FCGI_Accept(void);当一个请求被送达的时候返回。一个基本的fastcgi结构如下。
echo.c
#include "fcgi_stdio.h"#include
void main(void)
{//初始化一些全局变量,这里只在fastcgi启动时候运行一次
while(FCGI_Accept() >= 0) {//fastcgi的处理逻辑//根据http协议返回处理结果
printf("Content-type: text/html\r\n");
printf("\r\n");
printf("hello world");
}
}
3.编译echo.c
编译时候首先要安装fastcti
wget http://www.fastcgi.com/dist/fcgi.tar.gz
tar -zxvf fcgi.tar.gz
cd fcgi-2.4.1-SNAP-0311112127/
./configure --prefix=/etc/fcgi
make && make install
出现fcgio.cpp:50:
error: ‘EOF‘ was not declared in this scope的话 在/include/fcgio.h文件中加上
#include
到此就安装完了。然后我们来编译echo.c
gcc echo.c -o echo.cgi -I/etc/fcgi/include
-L/etc/fcgi/lib/ -lfcgi
注意-I -L -l都不能少。
4.lighttpd+fastcgi配置
lighttpd支持fastcgi需要安装fastcgi模块
yum install lighttpd-fastcgi
创建配置文件 vim /etc/fcgi/fcgi.conf
server.document-root = "/var/www/cgi-bin/"
server.port = 8080
server.username = "www-data"
server.groupname = "www-data"
server.modules = ("mod_access", "mod_accesslog", "mod_fastcgi")
server.errorlog = "/var/www/cgi-bin/error.log"
accesslog.filename = "/var/www/cgi-bin/access.log"
static-file.exclude-extensions = (".cgi" )
fastcgi.debug = 1
fastcgi.server = (
"echo.cgi" => ((
"host" => "127.0.0.1",
"port" => "9000",
"bin-path" => "/var/www/cgi-bin/echo.cgi",
))
)
lighttpd -D -f fcgi.conf 时候会出现error while loading shared libraries:
libfcgi.so.0: cannot open shared object file: No such file or
directory
反正就是找不到动态链接库,比较无脑的方式就是把fastcgi安装目录下的include和lib都拷贝到/usr/include 和
/usr/lib中。注意,不是/usr/local
设置过之后可能还是找不到,参考网上另一种方法是。
首先vim /etc/ld.so.conf 添加libfcgi.so.0的路径,然后运行/sbin/ldconfig,重新编译trie.cgi,ldd
trie.cgi一下,看到libfcgi.so.0找到就OKAY了。
在浏览器输入http://127.0.0.1:8080/echo.cgi 就可以看到hello world了
5.实例 输入提示
这次把他通过fastcgi的api改写成fastcgi程序。trie.c
#include "stdio.h"#include"stdlib.h"#include"string.h"#include"malloc.h"#include"fcgi_stdio.h"
char* strcatch(char *str, charch) {char *p =str;while (*p!=‘\0‘) {
p++;
}*p =ch;*(p+1) = ‘\0‘;returnstr;
}#define MAX_NODE 100000
#define ALPHA_COUNT 128typedefstructt_trie{intch[MAX_NODE][ALPHA_COUNT];intval[MAX_NODE];intsize;
}trie;
trie*create() {
trie*root = (trie *)malloc(sizeof(trie));
root->size = 1;
memset(root->ch[0], 0, sizeof(root->ch[0]));returnroot;
}void insert(trie *root, char *str, intn) {int i, cur = 0, pre =cur;for (i=0; ich[cur][c]) {
memset(root->ch[root->size], 0, sizeof(root->ch[root->size]));
root->val[root->size] = 0;
root->ch[cur][c] = root->size++;
}
cur= root->ch[cur][c];
}
root->val[cur] = 1;
}int search(trie *root, char *str) {int i, cur = 0, n =strlen(str);for (i=0; i
cur= root->ch[cur][c];
}if (root->val[cur]) {return 1;
}return 0;
}void suggest_helper(trie *root, char* str, int cur, int i, int *count) {if (*count > 9) {return;
}if (root->val[cur]) {*count = *count+1;char c = i+‘\0‘;
printf("
%s%c", str, c, str, c);}int j=0;for (j=0; jch[cur][j]) {char c = i+‘\0‘;char temp[128];
strcpy(temp, str);
strcatch(temp, c);
suggest_helper(root, temp, root->ch[cur][j], j, count);
}
}
}void suggest(trie *root, char *str) {int i, cur = 0, n = strlen(str), count=0;for (i=0; ich[cur][c]) {
cur= root->ch[cur][c];
}else{
printf("no suggestion found\n");return;
}
}for (i=0; ich[cur][i]) {
suggest_helper(root, str, root->ch[cur][i], i, &count);
}
}
}int http_get(char *key, char *query, char *result) {char *p =result;
query=strstr(query, key);int write = 0;while (*query) {if (*query==‘=‘) {
query++;
write= 1;continue;
}if(write) {if (*query==‘&‘) {*p = ‘\0‘;return 1;
}*p = *query;
p++;query++;
}else{
query++;
}
}*p = ‘\0‘;return 1;
}intmain() {
trie*root =create();charch;
FILE*fp;char line[255];
size_t len= 0;
ssize_t read;char keyword[64];if ((fp = fopen("phpfunc.txt", "r")) ==NULL) {
printf("open error\n");
exit(1);
}while (fgets(line, 255, fp) !=NULL) {char *end = strchr(line,‘\n‘);*end = ‘\0‘;
insert(root, line, strlen(line));
}while (FCGI_Accept() >= 0) {
printf("Content-Type:text/html; charset=utf-8\n\n");char *query = getenv("QUERY_STRING");
http_get("q", query, keyword);
suggest(root, keyword);
}return 0;
}
然后编译gcc trie.c -o trie.cgi -I/etc/fcgi/include -L/etc/fcgi/lib/ -lfcgi
修改fcgi.conf
fastcgi.server = (
"trie.cgi" => ((
"host" => "127.0.0.1",
"port" => "9000",
"bin-path" => "/var/www/cgi-bin/trie.cgi",
))
)
在浏览器输入http://127.0.0.1:8080/trie.cgi?q=var
可以看到输出var_dump:var_export:variant_abs:variant_add:variant_and:variant_cast:variant_cat:variant_cmp:variant_date_from_timestamp:variant_date_to_timestamp:
下面是编写前端JS请求
index.html
Ajax Auto Suggestfunctionlookup(inputString) {
$.get("http://192.168.2.165:8880/trie.cgi", {q:""+inputString+""},function(data){if(data.length>0) {
$(‘#suggestions‘).show();
$(‘#autoSuggestionsList‘).html(data);
}
});
}functionfill(thisValue) {
$(‘#inputString‘).val(thisValue);
setTimeout("$(‘#suggestions‘).hide();",200);
}
body{font-family:Helvetica;font-size:11px;
}h3{margin:0px;padding:0px;
}.suggestionsBox{position:relative;left:30px;margin:10px 0px 0px 0px;width:200px;-moz-border-radius:7px;-webkit-border-radius:7px;border:2px solid #000;
}.suggestionList{margin:0px;padding:0px;
}.suggestionList li{margin:0px 0px 3px 0px;padding:3px;cursor:pointer;
}.suggestionList li:hover{background-color:#659CD8;
}