基于libevent 1.3e, 利用了libevent里面现成的http库
编译方法,先安装libevent,然后
cc -o httpd httpd.c -L/usr/local/lib/ -Wall -O2 -I/usr/local/include -ggdb -levent
可以作为一个商业运行环境的基础,真正的业务系统里面,comet server也很简单,比这个程序复杂不了什么,它只处理comet,只是一个通道,复杂的东西放到其他地方。
打算作为下图中的一个模块
Source code:
#include <sys/types.h>
#include <sys/time.h>
#include <stdlib.h>
#include <err.h>
#include <sys/queue.h>
#include <evhttp.h>
#define MAX_CONN 10240
struct evhttp_request *requests[MAX_CONN];
struct evbuffer *bufs[MAX_CONN];
int pos[MAX_CONN], num;
void on_close(struct evhttp_request *req, void *arg) {
int* p = (int*) arg;
struct evhttp_request *p2 = requests[*p];
struct evbuffer *p3 = bufs[*p];
printf("%s closed.\n", p2->remote_host);
requests[*p] = NULL;
if (p3 != NULL) evbuffer_free(p3);
}
/* for comet recv */
void comet_handler(struct evhttp_request *req, void *arg) {
int i, j;
requests[num] = req;
struct evbuffer *buf;
req->minor = 0;
evhttp_add_header(req->output_headers, "Content-Type", "text/plain");
evhttp_send_reply_start(req, HTTP_OK, "OK");
/* Set a callback for connection close. */
evhttp_connection_set_closecb(req->evcon, on_close, &pos[num]);
buf = evbuffer_new();
bufs[num] = buf;
for (j = 0; j < 10; j++)
evbuffer_add_printf(buf, "Hi %s, this is a comet server based on libevent, visit http://hi.baidu.com/jabber for more information!\r\n", req->remote_host);
evhttp_send_reply_chunk(req, buf);
for (i = 0; i < num; i++) {
if (requests[i] == NULL) continue;
evbuffer_add_printf(bufs[i], "Oops, %s requests!\r\n", req->remote_host);
evhttp_send_reply_chunk(requests[i], bufs[i]);
// evhttp_send_reply_end(requests[i]);
}
if (num++ == MAX_CONN) err(1, "exceed max conn, TODO.");
}
/* for comet send, GET /id */
void notify_handler(struct evhttp_request *req, void *arg) {
struct evbuffer *buf;
int nudge;
buf = evbuffer_new();
if (buf == NULL) err(1, "failed to create response buffer");
const char *uri = evhttp_request_uri(req);
evbuffer_add_printf(buf, "Requested: %s, send a nudge to %s\n", uri, uri + 1);
nudge = atoi(uri + 1);
if (requests[nudge] != NULL) {
evbuffer_add_printf(bufs[nudge], "Oops, received a nudge from %s!\r\n", req->remote_host);
evhttp_send_reply_chunk(requests[nudge], bufs[nudge]);
}
evhttp_send_reply(req, HTTP_OK, "OK", buf); // TODO: free buf
}
int main(int argc, char **argv) {
struct evhttp *httpd;
int i;
for (i = 0; i < 1024; i++) {
requests[i] == NULL;
bufs[i] = NULL;
pos[i] = i;
}
num = 0;
event_init();
httpd = evhttp_start("0.0.0.0", 8080);
/* Set a comet callback for requests to "/". */
evhttp_set_cb(httpd, "/", comet_handler, NULL);
/* Set a send callback for all other requests. */
evhttp_set_gencb(httpd, notify_handler, NULL);
event_dispatch();
/* Not reached in this code as it is now. */
evhttp_free(httpd);
return 0;
}
http://www.chinaunix.net/jh/27/1088810.html
http://hi.baidu.com/jabber/blog/item/84aebc8f060f00eaf01f36b4.html
http://hi.baidu.com/jabber/blog/item/f556c7fcbaa76286b801a042.html
参考:
http://blog.gslin.org/archives/2005/11/24/220/ libevent编程介绍,里面的留言较搞笑
http://unx.ca/log/tag/libevent/ 比较旧了,基于libevent 1.2 的例子
http://www.slideshare.net/simon/time-for-comet/ 什么是 comet,这里有原理说明
类别:Web Im 查看评论
最简单的WEB服务器:
g++ -levent
#include<sys/types.h>
#include<sys/time.h>
#include<sys/queue.h>
#include<stdlib.h>
#include<err.h>
#include<event.h>
#include<evhttp.h>
void generic_handler(struct evhttp_request *req, void *arg)
{
struct evbuffer *buf;
buf = evbuffer_new();
if (buf == NULL)
err( "failed to create response buffer");
evbuffer_add_printf(buf, "Fuck you!", evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}
int main(int argc, char **argv)
{
struct evhttp *httpd;
event_init();
httpd = evhttp_start(", );
/* Set a callback for requests to "/specific". */
/* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */
/* Set a callback for all other requests. */
evhttp_set_gencb(httpd, generic_handler, NULL);
event_dispatch();
/* Not reached in this code as it is now. */
evhttp_free(httpd);
return
}
编译方法,先安装libevent,然后
cc -o httpd httpd.c -L/usr/local/lib/ -Wall -O2 -I/usr/local/include -ggdb -levent
可以作为一个商业运行环境的基础,真正的业务系统里面,comet server也很简单,比这个程序复杂不了什么,它只处理comet,只是一个通道,复杂的东西放到其他地方。
打算作为下图中的一个模块
Source code:
#include <sys/types.h>
#include <sys/time.h>
#include <stdlib.h>
#include <err.h>
#include <sys/queue.h>
#include <evhttp.h>
#define MAX_CONN 10240
struct evhttp_request *requests[MAX_CONN];
struct evbuffer *bufs[MAX_CONN];
int pos[MAX_CONN], num;
void on_close(struct evhttp_request *req, void *arg) {
int* p = (int*) arg;
struct evhttp_request *p2 = requests[*p];
struct evbuffer *p3 = bufs[*p];
printf("%s closed.\n", p2->remote_host);
requests[*p] = NULL;
if (p3 != NULL) evbuffer_free(p3);
}
/* for comet recv */
void comet_handler(struct evhttp_request *req, void *arg) {
int i, j;
requests[num] = req;
struct evbuffer *buf;
req->minor = 0;
evhttp_add_header(req->output_headers, "Content-Type", "text/plain");
evhttp_send_reply_start(req, HTTP_OK, "OK");
/* Set a callback for connection close. */
evhttp_connection_set_closecb(req->evcon, on_close, &pos[num]);
buf = evbuffer_new();
bufs[num] = buf;
for (j = 0; j < 10; j++)
evbuffer_add_printf(buf, "Hi %s, this is a comet server based on libevent, visit http://hi.baidu.com/jabber for more information!\r\n", req->remote_host);
evhttp_send_reply_chunk(req, buf);
for (i = 0; i < num; i++) {
if (requests[i] == NULL) continue;
evbuffer_add_printf(bufs[i], "Oops, %s requests!\r\n", req->remote_host);
evhttp_send_reply_chunk(requests[i], bufs[i]);
// evhttp_send_reply_end(requests[i]);
}
if (num++ == MAX_CONN) err(1, "exceed max conn, TODO.");
}
/* for comet send, GET /id */
void notify_handler(struct evhttp_request *req, void *arg) {
struct evbuffer *buf;
int nudge;
buf = evbuffer_new();
if (buf == NULL) err(1, "failed to create response buffer");
const char *uri = evhttp_request_uri(req);
evbuffer_add_printf(buf, "Requested: %s, send a nudge to %s\n", uri, uri + 1);
nudge = atoi(uri + 1);
if (requests[nudge] != NULL) {
evbuffer_add_printf(bufs[nudge], "Oops, received a nudge from %s!\r\n", req->remote_host);
evhttp_send_reply_chunk(requests[nudge], bufs[nudge]);
}
evhttp_send_reply(req, HTTP_OK, "OK", buf); // TODO: free buf
}
int main(int argc, char **argv) {
struct evhttp *httpd;
int i;
for (i = 0; i < 1024; i++) {
requests[i] == NULL;
bufs[i] = NULL;
pos[i] = i;
}
num = 0;
event_init();
httpd = evhttp_start("0.0.0.0", 8080);
/* Set a comet callback for requests to "/". */
evhttp_set_cb(httpd, "/", comet_handler, NULL);
/* Set a send callback for all other requests. */
evhttp_set_gencb(httpd, notify_handler, NULL);
event_dispatch();
/* Not reached in this code as it is now. */
evhttp_free(httpd);
return 0;
}
http://www.chinaunix.net/jh/27/1088810.html
http://hi.baidu.com/jabber/blog/item/84aebc8f060f00eaf01f36b4.html
http://hi.baidu.com/jabber/blog/item/f556c7fcbaa76286b801a042.html
参考:
http://blog.gslin.org/archives/2005/11/24/220/ libevent编程介绍,里面的留言较搞笑
http://unx.ca/log/tag/libevent/ 比较旧了,基于libevent 1.2 的例子
http://www.slideshare.net/simon/time-for-comet/ 什么是 comet,这里有原理说明
类别:Web Im 查看评论
最简单的WEB服务器:
g++ -levent
#include<sys/types.h>
#include<sys/time.h>
#include<sys/queue.h>
#include<stdlib.h>
#include<err.h>
#include<event.h>
#include<evhttp.h>
void generic_handler(struct evhttp_request *req, void *arg)
{
struct evbuffer *buf;
buf = evbuffer_new();
if (buf == NULL)
err( "failed to create response buffer");
evbuffer_add_printf(buf, "Fuck you!", evhttp_request_uri(req));
evhttp_send_reply(req, HTTP_OK, "OK", buf);
}
int main(int argc, char **argv)
{
struct evhttp *httpd;
event_init();
httpd = evhttp_start(", );
/* Set a callback for requests to "/specific". */
/* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */
/* Set a callback for all other requests. */
evhttp_set_gencb(httpd, generic_handler, NULL);
event_dispatch();
/* Not reached in this code as it is now. */
evhttp_free(httpd);
return
}
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:http://jackxiang.com/post/1904/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
最后编辑: jackxiang 编辑于2009-8-6 18:38
评论列表