libwebsockets(二) 간이 http 서버 구현

11869 단어 websockets
정부의 설명을 보면 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 */

        ...
};

프로토콜은 이 서버가 처리할 수 있는 프로토콜 형식을 가리키며 그룹 형식으로 제공되고 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를 참고할 수 있습니다. 여기서 우리는 첫 번째 함수를 사용합니다.

/*
 * 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 
 *
 * 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 
#include 
#include 

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
"
); context = lws_create_context(&info); if (!context) { lwsl_err("lws init failed
"
); return 1; } while (n >= 0 && !interrupted) n = lws_service(context, 1000); lws_context_destroy(context); return 0; }

좋은 웹페이지 즐겨찾기