现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

libwebsockets(二)实现简易http服务器

2019-09-03 17:48 工业·编程 ⁄ 共 4868字 ⁄ 字号 暂无评论

根据官方的说明来看,从2.0版本起,http协议的服务器已经自动集成在库中,不需要我们自己去实现。下面介绍如何使用库去实现http服务器。

1、填充服务器创建需要的参数

lws_context_creation_info是创建服务器句柄时用来定制服务器信息的结构体,所以我们首先需要填充该结构体。该结构体的定义如下。

/*这里只列出我们常用的成员,注释很详细,不做过多解释*/

struct lws_context_creation_info {

    int port;

    /**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppress

     * listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you are

     * writing a server but you are using \ref sock-adopt instead of the

     * built-in listener */

    const char *iface;

    /**< VHOST: NULL to bind the listen socket to all interfaces, or the

     * interface name, eg, "eth2"

     * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is

     * the pathname of a UNIX domain socket. you can use the UNIX domain

     * sockets in abstract namespace, by prepending an at symbol to the

     * socket name. */

    const struct lws_protocols *protocols;

    /**< VHOST: Array of structures listing supported protocols and a protocol-

     * specific callback for each one.  The list is ended with an

     * entry that has a NULL callback pointer. */

    const struct lws_extension *extensions;

    /**< VHOST: NULL or array of lws_extension structs listing the

     * extensions this context supports. */

    const char *log_filepath;

    /**< VHOST: filepath to append logs to... this is opened before

     *      any dropping of initial privileges */

    const struct lws_http_mount *mounts;

    /**< VHOST: optional linked list of mounts for this vhost */

        ...

};

protocols用来指明该服务器可以处理的协议类型,以数组的形式提供并NULL作为数组结尾,如果不指定则默认使用http协议。

mounts用来设置与http服务器相关的参数,比如主机路径、URL路径、默认的主页文件等等。我们在这里初始化如下:

    static const struct lws_http_mount mount = {

        /* .mount_next */               NULL,           /* linked-list "next" */

        /* .mountpoint */               "/",            /* mountpoint URL */

        /* .origin */                   ".",            /* serve from dir */

        /* .def */                      "index.html",   /* default filename */

        /* .protocol */                 NULL,

        /* .cgienv */                   NULL,

        /* .extra_mimetypes */          NULL,

        /* .interpret */                NULL,

        /* .cgi_timeout */              0,

        /* .cache_max_age */            0,

        /* .auth_mask */                0,

        /* .cache_reusable */           0,

        /* .cache_revalidate */         0,

        /* .cache_intermediaries */     0,

        /* .origin_protocol */          LWSMPRO_FILE,   /* files in a dir */

        /* .mountpoint_len */           1,              /* char count */

        /* .basic_auth_login_file */    NULL,

    };

    struct lws_context_creation_info info;

    /*初始化内存*/

    memset(&info, 0, sizeof info);

    info.port = 7681;

    info.mounts = &mount;

2、创建服务器句柄

调用的函数为

LWS_VISIBLE LWS_EXTERN struct lws_context* lws_create_context(struct lws_context_creation_info *info)  

当创建失败时,将会返回NULL。

    struct lws_context *context;

    context = lws_create_context(&info);

3、运行服务器

共有4个函数可以执行运行服务器,具体的介绍可以参见 api,这里我们使用第1个函数。

/*

* context: 服务器句柄;

* timeout_ms: 等待超时时间,即没有找到需要处理的连接需要等待的时间,为0则立即返回;

* pollfd: poll结构;

* tsi: 线程索引,默认为0;

*/

int lws_service (struct lws_context *context, int timeout_ms)

int lws_service_fd (struct lws_context *context, struct lws_pollfd *pollfd)

int lws_service_fd_tsi (struct lws_context *context, struct lws_pollfd *pollfd, int tsi)

int lws_service_tsi (struct lws_context *context, int timeout_ms, int tsi)     

直接调用lws_service即可。

    /*设置超时时间为1000ms*/

    lws_service(context, 1000);

4、整体代码

/*

* lws-minimal-http-server

*

* Copyright (C) 2018 Andy Green <andy@warmcat.com>

*

* This file is made available under the Creative Commons CC0 1.0

* Universal Public Domain Dedication.

*

* This demonstrates the most minimal http server you can make with lws.

*

* To keep it simple, it serves stuff in the directory it was started in.

* You can change that by changing mount.origin

*/

#include <libwebsockets.h>

#include <string.h>

#include <signal.h>

static int interrupted;

static const struct lws_http_mount mount = {

    /* .mount_next */       NULL,       /* linked-list "next" */

    /* .mountpoint */       "/",        /* mountpoint URL */

    /* .origin */           ".",        /* serve from dir */

    /* .def */          "index.html",   /* default filename */

    /* .protocol */         NULL,

    /* .cgienv */           NULL,

    /* .extra_mimetypes */      NULL,

    /* .interpret */        NULL,

    /* .cgi_timeout */      0,

    /* .cache_max_age */        0,

    /* .auth_mask */        0,

    /* .cache_reusable */       0,

    /* .cache_revalidate */     0,

    /* .cache_intermediaries */ 0,

    /* .origin_protocol */      LWSMPRO_FILE,   /* files in a dir */

    /* .mountpoint_len */       1,      /* char count */

    /* .basic_auth_login_file */    NULL,

};

void sigint_handler(int sig)

{

    interrupted = 1;

}

int main(int argc, char **argv)

{

    struct lws_context_creation_info info;

    struct lws_context *context;

    int n = 0;

    signal(SIGINT, sigint_handler);

    memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */

    info.port = 7681;

    info.mounts = &mount;

    lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER

            /* | LLL_INFO */ /* | LLL_DEBUG */, NULL);

    lwsl_user("LWS minimal http server | visit http://localhost:7681\n");

    context = lws_create_context(&info);

    if (!context) {

        lwsl_err("lws init failed\n");

        return 1;

    }

    while (n >= 0 && !interrupted)

        n = lws_service(context, 1000);

    lws_context_destroy(context);

    return 0;

}

给我留言

留言无头像?