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 <stdlib.h> void main(void)
{
//初始化一些全局变量,这里只在fastcgi启动时候运行一次
while(FCGI_Accept() >= ) {
//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 <cstdio>

到此就安装完了。然后我们来编译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.实例 输入提示

输入提示的具体实现方法已经在这篇博客里说过http://www.cnblogs.com/23lalala/p/3513492.html

这次把他通过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, char ch) {
char *p = str;
while (*p!='\0') {
p++;
}
*p = ch;
*(p+) = '\0';
return str;
} #define MAX_NODE 100000
#define ALPHA_COUNT 128 typedef struct t_trie{
int ch[MAX_NODE][ALPHA_COUNT];
int val[MAX_NODE];
int size;
}trie; trie* create() {
trie *root = (trie *)malloc(sizeof(trie));
root->size = ;
memset(root->ch[], , sizeof(root->ch[]));
return root;
} void insert(trie *root, char *str, int n) {
int i, cur = , pre = cur;
for (i=; i<n; i++) {
int c = str[i]-'\0';
if (!root->ch[cur][c]) {
memset(root->ch[root->size], , sizeof(root->ch[root->size]));
root->val[root->size] = ;
root->ch[cur][c] = root->size++;
}
cur = root->ch[cur][c];
}
root->val[cur] = ;
} int search(trie *root, char *str) {
int i, cur = , n = strlen(str);
for (i=; i<n; i++) {
int c = str[i]-'\0';
cur = root->ch[cur][c];
}
if (root->val[cur]) {
return ;
}
return ;
} void suggest_helper(trie *root, char* str, int cur, int i, int *count) {
if (*count > ) {
return;
}
if (root->val[cur]) {
*count = *count+;
char c = i+'\0';
printf("<li onclick=\"fill('%s%c')\">%s%c</li>", str, c, str, c);
}
int j=;
for (j=; j<ALPHA_COUNT; j++) {
if (root->ch[cur][j]) {
char c = i+'\0';
char temp[];
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 = , n = strlen(str), count=;
for (i=; i<n; i++) {
int c = str[i] - '\0';
if (root->ch[cur][c]) {
cur = root->ch[cur][c];
} else {
printf("no suggestion found\n");
return;
}
}
for (i=; i<ALPHA_COUNT; i++) {
if (root->ch[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 = ;
while (*query) {
if (*query=='=') {
query++;
write = ;
continue;
}
if (write) {
if (*query=='&') {
*p = '\0';
return ;
}
*p = *query;
p++;query++;
} else {
query++;
}
}
*p = '\0';
return ;
} int main() {
trie *root = create();
char ch;
FILE *fp;
char line[];
size_t len = ;
ssize_t read;
char keyword[];
if ((fp = fopen("phpfunc.txt", "r")) == NULL) {
printf("open error\n");
exit();
}
while (fgets(line, , fp) != NULL) {
char *end = strchr(line,'\n');
*end = '\0';
insert(root, line, strlen(line));
}
while (FCGI_Accept() >= ) {
printf("Content-Type:text/html; charset=utf-8\n\n");
char *query = getenv("QUERY_STRING");
http_get("q", query, keyword);
suggest(root, keyword);
}
return ;
}

然后编译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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax Auto Suggest</title>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.8.0.js"></script>
<script type="text/javascript">
function lookup(inputString) {
$.get("http://192.168.2.165:8880/trie.cgi", {q: ""+inputString+""}, function(data){
if(data.length >0) {
$('#suggestions').show();
$('#autoSuggestionsList').html(data);
}
});
} function fill(thisValue) {
$('#inputString').val(thisValue);
setTimeout("$('#suggestions').hide();", 200);
}
</script>
<style type="text/css">
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;
}
</style>
</head>
<body>
<div>
<form>
<div>
Type php functions:
<br />
<input type="text" size="30" value="" id="inputString" onkeyup="lookup(this.value);" onblur="fill();" />
</div>
<div class="suggestionsBox" id="suggestions" style="display: none;">
<img src="upArrow.png" style="position: relative; top: -12px; left: 30px;" alt="upArrow" />
<div class="suggestionList" id="autoSuggestionsList">
</div>
</div>
</form>
</div>
</body>
</html>

因为服务器需要解析html文件所以在fcgi.conf中添加

mimetype.assign = (
".html" => "text/html",
)

启动lighttpd sudo /usr/local/webserver/lighttpd/sbin/lighttpd -D -f /usr/local/webserver/lighttpd/conf/fcgi.conf

在浏览器输入http://127.0.0.1:8080/index.html 就可以访问了。

fastcgi,swoole都一定程度弥补了php这种对于开发者类似CGI模式(如果不写PHP扩展,实际就是CGI模式~)对于开发者在开发网站时候的诸多不足。下一篇会介绍thrift并且用thrift编写一个主键生成服务器。

fastcgi+lighttpd+c语言 实现搜索输入提示的更多相关文章

  1. JQuery+AJAX实现搜索文本框的输入提示功能

    平时使用谷歌搜索的时候发现只要在文本框里输入部分单词或字母,下面马上会弹出一个相关信息的内容框可供选择.感觉这个功能有较好的用户体验,所以也想在自己的网站上加上这种输入提示框. 实现的原理其实很简单, ...

  2. 【高德地图API】从零开始学高德JS API(四)搜索服务——POI搜索|自动完成|输入提示|行政区域|交叉路口|自有数据检索

    原文:[高德地图API]从零开始学高德JS API(四)搜索服务——POI搜索|自动完成|输入提示|行政区域|交叉路口|自有数据检索 摘要:地图服务,大家能想到哪些?POI搜素,输入提示,地址解析,公 ...

  3. 【高德地图API】从零開始学高德JS API(四)搜索服务——POI搜索|自己主动完毕|输入提示|行政区域|交叉路口|自有数据检索

    地图服务.大家能想到哪些?POI搜素,输入提示,地址解析,公交导航,驾车导航,步行导航,道路查询(交叉口),行政区划等等.假设说覆盖物Marker是地图的骨骼,那么服务,就是地图的气血. 有个各种各样 ...

  4. web开发如何使用高德地图API(二)结合输入提示和POI搜索插件

    说两句: 以下内容除了我自己写的部分,其他部分在高德开放平台都有(可点击外链访问). 我所整理的内容以实际项目为基础希望更有针对性的,更精简. 点击直奔主题. 准备工作: 首先,注册开发者账号,成为高 ...

  5. Springboot+Vue实现仿百度搜索自动提示框匹配查询功能

    案例功能效果图 前端初始页面 输入搜索信息页面 点击查询结果页面 环境介绍 前端:vue 后端:springboot jdk:1.8及以上 数据库:mysql 核心代码介绍 TypeCtrler .j ...

  6. C语言的基本输入与输出函数(全解)

    C语言的基本输入与输出函数 1.1.1 格式化输入输出函数 Turbo C2.0 标准库提供了两个控制台格式化输入. 输出函数printf() 和scanf(), 这两个函数可以在标准输入输出设备上以 ...

  7. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  8. WinForm AutoComplete 输入提示、自动补全

    一.前言 又临近春节,作为屌丝的我,又要为车票发愁了.记得去年出现了各种12306的插件,最近不忙,于是也着手自己写个抢票插件,当是熟悉一下WinForm吧.小软件还在开发中,待完善后,也写篇博客与大 ...

  9. Jquery实现搜索框提示功能

    博客的前某一篇文章中http://www.cnblogs.com/hEnius/p/2013-07-01.html写过一个用Ajax来实现一个文本框输入的提示功能.最近在一个管理项目的项目中,使用后发 ...

随机推荐

  1. mac 系统配置(一)

    1.终端颜色配置 文件 .bash_profile下添加环境变量如下: export CLICOLOR=1 export LSCOLORS=gxfxaxdxcxegedabagacad 环境变量生效: ...

  2. pyquery的简单操作

    一.初始化 1.html初始化 html = ''' <div> <ul> <li class="item-0">first item</ ...

  3. JavaEE 数据库随机值插入测试

    package com.jery.javaee.dbtest; import java.sql.Connection; import java.sql.DriverManager; import ja ...

  4. Tortoise SVN安装后右键没有菜单的解决方法

    最近换了WIN7的操作系统,感觉用起来爽极了,于是开始一个个装软件,最让我头疼的就是安装SVN,安装没有问题,完成后却无法显示右键菜单,开始同事也帮我找原因,以为是我设置问题或者哪里阻止了程序,还以为 ...

  5. 如何发布一个包到npm && 如何使用自己发布的npm包 && 如何更新发布到npm的package && 如何更新当前项目的包?

    如何发布一个包到npm First 在https://www.npmjs.com注册一个账号. Second 编辑好项目,文件大致如下: 其中,gitignore可以如下: .DS_Store nod ...

  6. cloudemanager安装时出现failed to receive heartbeat from agent问题解决方法(图文详解)

    不多说,直接上干货! 安装cdh5到最后报如下错误: 安装失败,无法接受agent发出的检测信号. 确保主机名称正确 确保端口7182可在cloudera manager server上访问(检查防火 ...

  7. MySql存储引擎MyISAM和InnoDB的区别

    1.MySQL默认采用的是MyISAM. 2.MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速 ...

  8. hibernate注解JPA

    1.JPA与hibernate 什么是JPA ? java persistence api :java持久化api,同一的ORM规范,是由sun公司指定的规范接口,hibernate实现了JPA规范. ...

  9. mysql应用学习-windows(64位)安装和配置mysql(5.6.20)

    下载安装包MySQL Installer 下载地址1:http://dev.mysql.com/downloads/windows/installer/ 说明:官网当前版本 5.6.22:虽然只有32 ...

  10. C#中TransactionScope的使用方法和原理(摘)

    出自51CTO博客:http://cnn237111.blog.51cto.com/2359144/1271600 在.net 1.1的时代,还没有TransactionScope类,因此很多关于事务 ...