web-dev-qa-db-fra.com

Meilleure méthode pour créer une application c ++ pour communiquer avec nginx

J'ai besoin d'écrire une interface C++ qui peut lire notre structure de données et fournir l'o/p basé sur la requête en utilisant le protocole http.

Besoin du serveur
Il devrait pouvoir servir 100 clients en même temps.

Pourquoi C++
Tout le code est déjà écrit en C++. Nous devons donc simplement écrire une couche http en C++. C'est pourquoi je choisis C++ au lieu d'un langage de programmation Web plus conventionnel.

Je pense utiliser nginx pour servir des fichiers statiques et utiliser sa passe proxy pour communiquer avec C++.

Il y a deux approches que j'ai trouvées:

  • Écrivez un module FastCGI c ++.

  • Écrivez un module c ++ node.js.

  • Veuillez juste toute autre suggestion si vous avez

Pouvez-vous énumérer les avantages et les inconvénients de chaque méthode en fonction de votre expérience antérieure?

36
Vivek Goel

Je pense que je vais aller de l'avant avec le développement du module Nginx http://www.evanmiller.org/nginx-modules-guide.html

Pourquoi ?

  1. Il ne nécessite aucune autre dépendance de bibliothèque comme fastcgi et autres.
  2. Je peux utiliser toutes les fonctionnalités de nginx dans mon module.
12
Vivek Goel

Personne ici ne semble avoir abordé la question réelle, bien que de belles solutions aient été proposées. J'ai pu créer des modules C++ pour nginx avec quelques modifications mineures.

  1. Modifiez le nom du fichier source du module pour qu'il se termine par .cpp afin que gcc se rend compte qu'il traite C++.
  2. Assurez-vous que tous vos nginx inclus (par exemple ngx_config.h, ngx_core.h, etc.) sont enveloppés avec une structure externe "C" {}. De même, assurez-vous que toutes les fonctions appelées via les pointeurs de fonction nginx sont déclarées avec un wrapper.
  3. Ajoutez --with-ld-opt = "- lstdc ++" à votre appel "configure" lors de la configuration de nginx.

Avec ces trois étapes, votre module devrait compiler, construire, lier et réellement fonctionner.

18
Christopher Smith

Ce que vous demandez, c'est essentiellement comment transformer le processus c ++ qui contient vos structures de données en serveur Web. Ce n'est peut-être pas la meilleure façon de procéder. (Là encore, c'est peut-être dans votre situation. Cela dépend de la complexité des interfaces du processus c ++ que vous essayez d'exposer, je suppose.)

Quoi qu'il en soit, j'essaierais de coller un petit frontend http entre le processus c ++ et les clients qui pourraient faire le travail http et communiquer avec le processus backend c ++ en utilisant un protocole de messagerie simple comme ZeroMQ/zmq .

zmq en c/c ++ est assez simple, et c'est très efficace et très rapide. En utilisant zmq, vous pouvez configurer très rapidement un simple serveur Web frontal en python, ou dans la langue que vous préférez qui a liaisons zmq , et faire en sorte que ce serveur frontal communique de manière asynchrone ou synchrone avec le processus c ++ backend en utilisant zmq.

Les exemples c ++ et le guide sont de bons points de départ si vous envisagez d'utiliser zmq.

Pour Node.js, il y a aussi quelques exemples .

10
Kimmeh

Essayez G-WAN, il vous permet d'utiliser directement votre application c ++.

4
Peter

Vous pouvez essayer fonction nginx c

Il est simple à utiliser et intégré dans la mémoire cache nginx sur la couche des applications, wiki pour la fonction nginx c

Exemple de projet avec cpp

Exemple de code:

#include <stdio.h>
#include <ngx_http_c_func_module.h>

/*** build the program as .so library and copy to the preferred place for nginx to link this library ***/
/*** gcc -shared -o libcfuntest.so -fPIC cfuntest.c ***/
/*** cp libcfuntest.so /etc/nginx/ ***/

int is_service_on = 0;

void ngx_http_c_func_init(ngx_http_c_func_ctx_t* ctx) {
    ngx_http_c_func_log(info, ctx, "%s", "Starting The Application");


    is_service_on=1;
}



void my_app_simple_get_greeting(ngx_http_c_func_ctx_t *ctx) {
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get");

    ngx_http_c_func_write_resp(
        ctx,
        200,
        "200 OK",
        "text/plain",
        "greeting from ngx_http_c_func testing"
    );
}

void my_app_simple_get_args(ngx_http_c_func_ctx_t *ctx) {
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_args");

    ngx_http_c_func_write_resp(
        ctx,
        200,
        "200 OK",
        "text/plain",
        ctx->req_args
    );
}

void my_app_simple_get_token_args(ngx_http_c_func_ctx_t *ctx) {
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_token_args");

    char * tokenArgs = ngx_http_c_func_get_query_param(ctx, "token");
    if (! tokenArgs) {
        ngx_http_c_func_write_resp(
            ctx,
            401,
            "401 unauthorized",
            "text/plain",
            "Token Not Found"
        );
    } else {
        ngx_http_c_func_write_resp(
            ctx,
            401,
            "401 unauthorized",
            "text/plain",
            tokenArgs
        );
    }
}

void my_app_simple_post(ngx_http_c_func_ctx_t *ctx) {
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_post");

    ngx_http_c_func_write_resp(
        ctx,
        202,
        "202 Accepted and Processing",
        "text/plain",
        ctx->req_body
    );
}



void my_app_simple_get_no_resp(ngx_http_c_func_ctx_t *ctx) {
    ngx_http_c_func_log_info(ctx, "Calling back and log from my_app_simple_get_no_resp");


}

void ngx_http_c_func_exit(ngx_http_c_func_ctx_t* ctx) {
    ngx_http_c_func_log(info, ctx, "%s\n", "Shutting down The Application");

    is_service_on = 0;
}
1
Oktaheta