zoukankan      html  css  js  c++  java
  • Goahead编译


    title: Goahead编译
    date: 2019/11/6 09:45:01
    toc: true

    Goahead 编译

    目录说明

    Makefile #顶层Makefile,可以自动检测当前运行平台的环境,并调用projects的mk
    projects #子层的Makefile,有各个平台的
    test     # web 文件以及路由和配置文件
    
    #可以看到直接make 输出如下
    make --no-print-directory -f projects/goahead-linux-default.mk all
    
    # 安装
    sudo make install
    

    Ubuntu编译

    make

    make
    sudo make install
    

    selfkey处理

    reallin@ubuntu:/work/goahead/goahead-5.0.1$ sudo goahead -v --home /etc/goahead /var/www/goahead
    goahead: 0: Unable to read key self.key
    goahead: 0: Cannot initialize server. Exiting.
    
    sudo cp ./build/linux-x64-default/bin/self.key /etc/goahead
    sudo cp ./build/linux-x64-default/bin/self.crt  /etc/goahead
    

    测试

    #./goahead -v --home 配置文件路径 文档路径 绑定IP:监听端口
    #./goahead -v --home /etc/goahead /var/www/goahead 0.0.0.0:8888
    sudo goahead -v --home /etc/goahead /var/www/goahead
    
    
    # 下面是运行结果
    goahead: 2: Configuration for Embedthis GoAhead Community Edition                           
    goahead: 2: ---------------------------------------------                                   
    goahead: 2: Version:            5.0.1                                                       
    goahead: 2: BuildType:          Debug                                                       
    goahead: 2: CPU:                x64                                                         
    goahead: 2: OS:                 linux                                                       
    goahead: 2: Host:               127.0.1.1                                                   
    goahead: 2: Directory:          /etc/goahead                                                
    goahead: 2: Documents:          /var/www/goahead                                            
    goahead: 2: Configure:          me -d -q -platform linux-x86-default -configure . -gen make 
    goahead: 2: ---------------------------------------------                                   
    goahead: 2: Started http://*:80                                                             
    goahead: 2: Started https://*:443                                                           
    

    具体的install目录

    ls /etc/goahead
    auth.txt  route.txt  self.crt  self.key
    
    ls /var/www/goahead
    favicon.ico  index.html  # 这个就是网页了
    

    交叉编译

    # 如果有错误提示 undefined reference to `__stack_chk_fail'  加上这个选项-fno-stack-protector
    make CC=arm-linux-gcc LD=arm-linux-ld CFLAGS=-fno-stack-protector
    

    方便测试

    1. cd build/linux-x64-default/bin

    2. cp ../../../src/auth.txt ./

    3. cp ../../../src/route.txt ./

    4. 新建一个myweb文件夹存网页

    5. sudo ./goahead -v ./myweb/

    6. 修改配置文件route.txt

      1.把route uri=/action handler=action注释掉
      	在前面加个#即可
      	然后加一句route uri=/action/ methods=GET|POST handler=action
      2. 把route uri=/ extensions=jst handler=jst改为route uri=/ extensions=jst,asp,html handler=jst
      	如果不做修改那我们在以后写html,asp文件里的action就不能被识别
      

    win下编译

    顶层目录的make.bat 修改下,因为原来的默认工程找不到路径

    projectswindows x64 nmake -f projects/goahead-windows-default.nmake %1 %2 %3 %4 %5 %6 %7 %8 %9
    

    运行之后,打开projects下的goahead-windows-default.sln就可以编译了

    如果要调试,需要设置调试目录为 ../../test,加上参数-v即可

    可以选择启动项目为test或者goahead.

    早期的源码流程

    --------------------------------------------------------------------------------------
    MAIN(goahead, int argc, char **argv, char **envp)
    -------------------------------------初始化过程开始-------------------------------------
    |-->for(argv[...]){}  //解析命令行
    |-->initPlatform();   //注册信号处理函数
        |-->signal(SIGTERM, sigHandler) ...
    |-->websOpen(documents, route)  //初始化服务器
        |-->websOsOpen();         //生成系统启动随机数(标识系统)
        |-->websRuntimeOpen(); //开始系统计时sym、symMax
        |-->websTimeOpen();      //初始化hash结构timeTokens
        |-->logOpen();                //初始化基本日志
        |-->setFileLimits();          //设置最大文件描述符值
        |-->socketOpen();           //初始化WebsSocket **socketList=NULL,socketMax =0,socketHighestFd=-1
        |-->setLocalHost();          //设置服务器的hostname(websHost), 服务器的IP地址(websIpAddr)
        |-->sslOpen();                 //若支持ssl则初始化ssl相关信息
        |-->sessions = hashCreate(-1);   //初始化话hash结构sessions
        |-->websStartEvent(...pruneSessions...);   //启动定时调度函数pruneSessions ,pruneSessions每秒调度清除过期的sessions
        |-->websSetDocuments(documents);        //设置goahead访问根目录websDocuments
        |-->websOpenRoute();     //初始化hash结构handlers,相应函数加入到handlers中.
            |-->websDefineHandler("continue", continueHandler, 0, 0, 0);  //continue的处理函数为continueHandler
            |-->websDefineHandler("redirect", redirectHandler, 0, 0, 0);    //redirect处理函数为redirectHandler
        |-->websCgiOpen();       //定义cgi处理函数加入到handlers中.
            |-->websDefineHandler("cgi", 0, cgiHandler, 0, 0);                 //定义cgi的处理函数为cgiHandler
        |-->websOptionsOpen(); //定义options处理函数加入到handlers中.
            |-->websDefineHandler("options", 0, optionsHandler, 0, 0);     //定义options的处理函数为optionsHandler
        |-->websActionOpen();    //初始化hash结构actionTable,定义action处理函数加入到handlers中,定义action对应值的函数加入到actionTable中. .
            |-->websDefineHandler("action", 0, actionHandler, closeAction, 0);   //定义action的处理函数为actionHandler
            |-->WebActionDefineInit();  //初始化action对应值的处理函数
                |-->websDefineAction("upgrade", ActionDefault); //定义action=upgrade的处理函数为ActionDefault,
                |-->websDefineAction("...", ...);                         //同上的类似函数
        |-->websFileOpen();       //设置默认页面websIndex="index.html",定义action处理函数加入到handlers中
            |-->websDefineHandler("file", 0, fileHandler, fileClose, 0);  //定义file的处理函数为fileHandler
        |-->websUploadOpen();  //设置上传文件路径uploadDir = "/tmp",定义upload处理函数加入到handlers中
            |-->websDefineHandler("upload", 0, uploadHandler, 0, 0);  //定义upload的处理函数为uploadHandler
        |-->websJstOpen();       //初始化hash结构websJstFunctions,定义write处理函数加入到websJstWrite中,定义jst处理函数加入到jstHandler中.
            |-->websDefineJst("write", websJstWrite);                        //定义jst(javascript)的write的处理函数为websJstWrite,支持<% write("text"); %>
            |-->websDefineHandler("jst", 0, jstHandler, closeJst, 0);     //定义jst(javascript)的处理函数为jstHandler
        |-->websOpenAuth(0);   //初始化认证相关处理函数
            |-->websDefineAction("userlogin", ActionUserLoginProc);     //定义action=userlogin的处理函数为ActionUserLoginProc
            |-->websDefineAction("userlogout", ActionUserLogoutProc); //定义action=userlogin的处理函数为ActionUserLoginProc
            |-->verifyPassword = websVerifyPasswordFromFile;            //设置验证密码函数
        |-->websFsOpen(0);   //初始化hash结构romFs,定义ME_ROM相关文件路径
        |-->websLoad(routeFile); //load route.txt配置文件
            |-->route = websAddRoute(uri, handler, -1)  //将结构为WebsRoute的route加入hash结构routes中,初始化route中uri和handler
            |-->websSetRouteMatch(route, dir, protocol, methods, extensions, abilities, redirects); //初始化route中protocol等
            |-->websSetRouteAuth(route, auth)              //初始化route中authType等
        |-->for(websMimeList){hashEnter(websMime)}  //初始化goahead默认支持的content type
        |-->open(accessLog, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, 0666)  //初始化access.log log日志文件
    |-->websLoad(auth)  //load auth.txt配置文件
        |-->websAddRole(name, abilities) //增加管理角色,如role name=manager abilities=view,edit,delete
        |--> websAddUser(username, password, roles)  //增加管理用户,如user name=admin password=xx roles=manager,purchaser
    ---------------------------------------初始化过程结束-------------------------------------------
    |-->logHeader();  //日志打印goahead基本配置信息
    |-->websListen(endpoint)  //初始化socket并监听
        |-->socketParseAddress(endpoint, &ip, &port, &secure, 80);  //解析监听ip 端口
        |-->sid = socketListen(ip, port, websAccept, 0)                      //创建socket,并监听,初始化WebsSocket结构加入到socketlist中
        |-->listens[listenMax++] = sid                                              //保存socket的WebsSocket信息到listens中
    |-->websGetBackground()  //使用daemon(0, 0)设置后台运行
    ---------------------------------------主循环处理开始-------------------------------------------
    |-->websServiceEvents(&finished);  //while(!finished){}主循环
        |-->socketSelect(-1, delay)  //select socket
            |-->nEvents = select(socketHighestFd + 1, (fd_set *) readFds, (fd_set *) writeFds, (fd_set *) exceptFds, &tv);  //select socket
        |-->socketProcess()            //处理请求
            |-->socketDoEvent(sp);
                |-->socketAccept(sp);   //accept新请求
                    |-->newSock = accept(sp->sock, addr, (Socklen*) &len)            //accept 新socket
                    |-->nid = socketAlloc(sp->ip, sp->port, sp->accept, sp->flags);  //分配并初始化新的WebsSocket,加入到socketList[nid]
                    |-->socketList[nid] ->sock = newSock ...                                   //继续初始化新的socketList[nid]的WebsSocket结构
                    |-->(sp->accept)(nid, ipbuf, port, sp->sid)                                //调用websAccept函数, nid为新建请求的socketid, ipbuf为远端IP,port为远端port, sp->sid为本机监听的socketid
                        |-->wid = websAlloc(sid);wp=webs[wid];    //根据参数sid(即nid)分配并初始化新的Webs,加入到webs[wid]
                            |-->initWebs(wp, 0, 0);        //初始化新的webs[wid]的Webs结构 
                                 |-->wp->state = WEBS_BEGIN;              //初始化链接状态机初始值
                                 |-->bufCreate(&wp->output);                //初始化发送buf
                                 |-->bufCreate(&wp->input);                  //初始化接收buf
                        |-->wp->listenSid = listenSid; ...                 //继续初始化新的webs[wid]的Webs结构
                        |-->wp->timeout = websStartEvent(PARSE_TIMEOUT, checkTimeout, (void*) wp);  //设置wp的超时函数
                        |-->socketEvent(sid, SOCKET_READABLE, wp); //
                            |-->readEvent(wp);            //一直调用readEvent读http和处理http,直至处理接收设置SOCKET_WRITABLE才可调用writeEvent
                                 |-->nbytes = websRead(wp, (char*) rxbuf->endp, ME_GOAHEAD_LIMIT_BUFFER)                //读取http报文
                                 |-->websPump(wp);          //根据wp->state状态机的值处理http报文
                                      |-->case WEBS_BEGIN:       parseIncoming(wp);  
                                           |-->parseFirstLine(wp);           //处理http请求行,并保存到wp结构中
                                           |-->parseHeaders(wp);           //处理http请求头部,并保存到wp结构中
                                           |-->wp->state = (wp->rxChunkState || wp->rxLen > 0) ? WEBS_CONTENT : WEBS_READY;  //设置wp->state状态值
                                           |-->websRouteRequest(wp);    //设置此链接的处理函数
                                      |-->case WEBS_CONTENT:   processContent(wp);
                                           |-->websProcessCgiData(wp);  //设置此链接的处理函数jstHandler、cgiHandler、continueHandler、redirectHandler、actionHandler等   
                                      |-->case WEBS_READY:        websRunRequest(wp);    
                                           |-->(*route->handler->service)(wp);   //执行此链接的处理函数,
                                                |-->hashLookup(actionTable, actionName);(*fn)((void*) wp);  //以actionHandler为例,执行actionTable中对应函数,以ActionDefault为例
                                                     |-->ActionDefault
                                                          |-->websWrite_ex(webs, 0, json_object_to_json_string(obj),token);  //返回页面数据  
                                                |-->jstHandler(Webs *wp);  //以jstHandler为例,执行...      
                                                          |-->...websDone(wp);
                                                               |-->websFlush(wp, 0);  -->wp->state = WEBS_COMPLETE;            
                                                               |-->socketCreateHandler(wp->sid, sp->handlerMask | SOCKET_WRITABLE, socketEvent, wp);                                                                                                  
                                      |-->case WEBS_RUNNING:      /* Nothing to do until websDone is called */
                                      |-->case WEBS_COMPLETE:  complete(wp, 1);                                                   
                                 |-->socketCreateHandler(wp->sid, sp->handlerMask | SOCKET_READABLE, socketEvent, wp); //初始化此链接的处理函数sp->handler=socketEvent
                            |-->writeEvent(wp);
                                 |-->websFlush(wp, 0);
                                      |-->while(websWriteSocket());  
                                      |-->wp->state = WEBS_COMPLETE;
                            |-->websFree(wp);
                |-->(sp->handler)(sid, sp->handlerMask & sp->currentEvents, sp->handler_data)   //
        |-->websCgiPoll();        //如有cgi,只响应cgi
        |-->websRunEvents();   //执行已加入定时器相关函数
    |-->websClose();              //关闭相关资源
    
  • 相关阅读:
    高性能 Socket 组件 HP-Socket v3.1.3 正式发布
    【新年呈献】高性能 Socket 组件 HP-Socket v3.1.2 正式发布
    更新整理本人所有博文中提供的代码与工具(Java,2014.01)
    更新整理本人所有博文中提供的代码与工具(C++,2014.01)
    【圣诞呈献】高性能 Socket 组件 HP-Socket v3.1.1 正式发布
    更新整理本人所有博文中提供的代码与工具(Java,2013.11)
    更新整理本人所有博文中提供的代码与工具(C++,2013.11)
    高性能 Windows Socket 组件 HP-Socket v3.0.2 正式发布
    高效 Java Web 开发框架 JessMA v3.3.1 正式发布
    高效 Java Web 开发框架 JessMA v3.3.1 Beta-1 发布
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/12109379.html
Copyright © 2011-2022 走看看