goahead-3.3.6源码分析

来源:互联网 发布:消防三知四会一联通 编辑:程序博客网 时间:2024/05/29 11:20

主要分为访问网页文件以及接口的调用逻辑
首先网页访问流程:网页访问事件注册 程序中需要返回html网页文件已经相关的图片、css等资源

这里写图片描述
上面的流程是直接使用websDefineHandler来把响应网页访问的事务添加到事务表,具体的网页文件返回的逻辑则在fileHandler函数中处理 最后使用send函数发送到对应的TCP链路上

// fileHandler函数判断和处理需要返回到浏览器的html文件数据static bool fileHandler(Webs *wp){    WebsFileInfo    info;    char            *tmp, *date;    ssize           nchars;    int             code;    int result;    assert(websValid(wp));    assert(wp->method);    assert(wp->filename && wp->filename[0]);    printf("%s(%d)filename=%s\n", __FILE__, __LINE__, wp->filename); // filename=/web/index.html    printf("%s(%d)method=%s\n", __FILE__, __LINE__, wp->method);    // method=GET    /*        If the file is a directory, redirect using the nominated default page         如果这里的文件路径是一个目录,则使用指定的默认(html)页面     */    if (websPageIsDirectory(wp)) { // 返回值 0=文件, 1=目录        nchars = strlen(wp->path);        if (wp->path[nchars - 1] == '/' || wp->path[nchars - 1] == '\\') {            wp->path[--nchars] = '\0';        }        tmp = sfmt("%s/%s", wp->path, websIndex);        websRedirect(wp, tmp);        wfree(tmp);        return 1;    }else{        printf("%s(%d)call websPageIsDirectory %s, >>> no a directory\n", __FILE__, __LINE__, wp->filename);    }    if (websPageOpen(wp, O_RDONLY | O_BINARY, 0666) <= 0) { //这里在移植到wince的过程有所改动,如果打不开(html)文件返回0        websError(wp, HTTP_CODE_NOT_FOUND, "Cannot open document for: %s", wp->path);        return 1;    }    if (websPageStat(wp, &info) < 0) { // 这里使用了GetFileAttributesEx(与ce系统相关接口)获取文件大小 修改时间等属性        websError(wp, HTTP_CODE_NOT_FOUND, "Cannot stat page for URL");        return 1;    }    code = 200;    if (wp->since && info.mtime <= wp->since) {        // 比较html文件的时间 如果不合法 则返回304        code = 304;        info.size = 0;    }    websSetStatus(wp, code);    websWriteHeaders(wp, info.size, 0);    if ((date = websGetDateString(&info)) != NULL) {        websWriteHeader(wp, "Last-Modified", "%s", date);        wfree(date);    }    websWriteEndHeaders(wp);    /*        All done if the browser did a HEAD request 没有头部请求时调用websDone返回     */    if (smatch(wp->method, "HEAD")) {        websDone(wp);        return 1;    }    if (info.size > 0) {        websSetBackgroundWriter(wp, fileWriteEvent);    } else {        websDone(wp);    }    return 1;}

goahead作为一个web服务器端 需要等待浏览器端的接入 所以需要等待事件的发生 这里使用了阻塞的方式进行事件等待 具体流程如下

这里写图片描述

PUBLIC void websServiceEvents(int *finished){    WebsTime    delay, nextEvent;    if (finished) {        *finished = 0;    }    delay = 0;    while (!finished || !*finished) {        if (socketSelect(-1, delay)) {            socketProcess();        }        delay = MAXINT;        nextEvent = websRunEvents();        delay = min(delay, nextEvent);    }}

API注释翻译:
基本事件循环,socketready返回true当一个套接字准备好服务。socketselect将阻塞直到事件发生。socketprocess实际上为服务进程
websServiceEvents函数在main函数的之后调用 处于循环状态 程序不会退出 平时处于阻塞状态等待浏览器端发送请求并进行处理 处理完成进入下一轮等待

这里写图片描述
以上在事件到来时 调用到fileHandler函数里面的流程

原创粉丝点击