zl程序教程

您现在的位置是:首页 >  硬件

当前栏目

SPWebServer:一个基于 SPServer 的 web 服务器框架

服务器Web框架 一个 基于
2023-09-27 14:27:56 时间

看到这个题目,估计很多人会问:为什么要再实现一个 web 服务器?

这里有几个原因:

1.这是一个 web 服务器框架,不是一个完整的 web 服务器。也就是说 SPWebServer 提供的是一套 API 和类库,可以方便地集成到现有的应用程序中。可以称 SPWebServer 为 embedded web server 。

2.有些时候,我们需要的不是一个功能强大完整的 web 服务器(例如 apache ),我们只是需要一个能提供最基本的 http 功能的服务器框架。比如要用 C/C++ 实现 XML-RPC,JSON-RPC 服务器端,或者为 jabberd 实现一个 http bind 的时候。这些场景下,也可以使用 apache,但是使用 embedded web server 可以简化配置。

3.在如下的场合中,apache 显得不合适,而 embedded web server 却正好合适:在一个现有的应用程序中,用 http 接口来提供一些简单的控制和统计功能。

基于以上原因,也为了 
1.丰富 SPServer 项目(请参考: SPServer : 一个基于 Half-Sync/Half-Async 模式的高并发 server 框架)的功能; 
2.正好作为 SPServer 框架的一个比较好的示范例子; 
因此基于 SPServer 框架实现了一个 web 服务器框架。

源代码下载: 
http://spserver.googlecode.com/files/spserver-0.5.src.tar.gz 
http://code.google.com/p/spserver/downloads/list

下面来看一个使用 SPWebServer 的简单例子。

ExpandedBlockStart.gifclass SP_HttpEchoHandler : public SP_HttpHandler {   
InBlock.gifpublic:   
ExpandedSubBlockStart.gif    SP_HttpEchoHandler(){}   
ExpandedSubBlockStart.gif    virtual ~SP_HttpEchoHandler(){}   
InBlock.gif  
ExpandedSubBlockStart.gif    virtual void handle( SP_HttpRequest * request, SP_HttpResponse * response ) {   
InBlock.gif        response- setStatusCode( 200 );   
InBlock.gif        response- appendContent( " html head "   
InBlock.gif            " title Welcome to simple http /title "   
InBlock.gif            " /head body    
InBlock.gif  
ExpandedSubBlockStart.gif        char buffer[ 512 ] = { 0 };   
InBlock.gif        snprintf( buffer, sizeof( buffer ),   
InBlock.gif            " p The requested URI is : %s. /p ", request- getURI() );   
InBlock.gif        response- appendContent( buffer );   
InBlock.gif  
InBlock.gif        snprintf( buffer, sizeof( buffer ),   
InBlock.gif            " p Client IP is : %s. /p ", request- getClientIP() );   
InBlock.gif        response- appendContent( buffer );   
InBlock.gif  
ExpandedSubBlockStart.gif        for( int i = 0; i   request- getParamCount(); i++ ) {   
InBlock.gif            snprintf( buffer, sizeof( buffer ),   
InBlock.gif                " p Param - %s = %s p ", request- getParamName( i ),   
InBlock.gif                request- getParamValue( i ) );   
InBlock.gif            response- appendContent( buffer );   
ExpandedSubBlockEnd.gif        }          
InBlock.gif  
ExpandedSubBlockStart.gif        for( int i = 0; i   request- getHeaderCount(); i++ ) {   
InBlock.gif            snprintf( buffer, sizeof( buffer ),   
InBlock.gif                " p Header - %s: %s p ", request- getHeaderName( i ),   
InBlock.gif                request- getHeaderValue( i ) );   
InBlock.gif            response- appendContent( buffer );   
ExpandedSubBlockEnd.gif        }          
InBlock.gif  
ExpandedSubBlockStart.gif        if( NULL != request- getContent() ) {   
InBlock.gif            response- appendContent( " p    
InBlock.gif            response- appendContent( request- getContent(),   
InBlock.gif                request- getContentLength() );   
InBlock.gif            response- appendContent( " /p    
ExpandedSubBlockEnd.gif        }          
InBlock.gif  
InBlock.gif        response- appendContent( " /body /html \n" );   
ExpandedSubBlockEnd.gif    }      
ExpandedBlockEnd.gif};   
None.gif  
ExpandedBlockStart.gifclass SP_HttpEchoHandlerFactory : public SP_HttpHandlerFactory {   
InBlock.gifpublic:   
ExpandedSubBlockStart.gif    SP_HttpEchoHandlerFactory(){}   
ExpandedSubBlockStart.gif    virtual ~SP_HttpEchoHandlerFactory(){}   
InBlock.gif  
ExpandedSubBlockStart.gif    virtual SP_HttpHandler * create() const {   
InBlock.gif        return new SP_HttpEchoHandler();   
ExpandedSubBlockEnd.gif    }   
ExpandedBlockEnd.gif};   
None.gif  
None.gif//---------------------------------------------------------   
None.gif  
None.gifint main( int argc, char * argv[] )   
ExpandedBlockStart.gif{   
InBlock.gif    int port = 8080;   
InBlock.gif  
InBlock.gif    SP_Server server( "", port,   
InBlock.gif        new SP_HttpHandlerAdapterFactory( new SP_HttpEchoHandlerFactory() ) );   
InBlock.gif  
InBlock.gif    server.runForever();   
InBlock.gif  
InBlock.gif    return 0;   
ExpandedBlockEnd.gif}   
None.gif

上面的代码演示的是一个 http echo server ,即把 client 发过来的请求信息显示在页面上。

在最简单的情况下,使用 SPWebServer 需要实现两个类:SP_HttpHandler 的子类 和 SP_HttpHandlerFactory 的子类。 
SP_HttpHandler 的子类负责处理具体的 http 请求。 
SP_HttpHandlerFactory 的子类协助 spserver 为每一个连接创建一个 SP_HttpHandler 子类实例。

在实现过程中,使用了 Adapter 模式,把 SP_HttpHandler 和 SP_HttpHandlerFactory 适配为 SP_Handler 和 SP_HandlerAdapterFactory。这两个 Adapter 都已经实现,不需要使用者来实现。


还能把浏览器当作 Web 服务器?骚操作,学废了~ 什么?还能把浏览器当作 Web 服务器? 闲话少说,直接干货! 整体思路:PWA 中用于缓存文件的 server workers 可以动态生成新文件,并通过 fetch 事件,将它们发送至浏览器!