web-dev-qa-db-ja.com

nginxと通信するC ++アプリを作成する最良の方法

データ構造を読み取り、httpプロトコルを使用したクエリに基づいてo/pを提供できるC++インターフェイスを作成する必要があります。

サーバーの必要性
同時に100のクライアントにサービスを提供できるはずです。

なぜC++
すべてのコードはすでにC++で記述されています。したがって、C++でhttpレイヤーを作成する必要があります。そのため、より一般的なWebプログラミング言語ではなくC++を選択しています。

Nginxを使用して静的ファイルを提供し、そのプロキシパスを使用してC++と通信することを考えています。

私が見つけた2つのアプローチがあります:

  • FastCGI c ++モジュールを記述します。

  • Node.js c ++モジュールを記述します。

  • もしあれば他の提案をしてください

以前の経験に基づいて、各方法の長所と短所を挙げていただけますか?

36
Vivek Goel

私はNginxモジュールの開発を進めると思います http://www.evanmiller.org/nginx-modules-guide.html

どうして ?

  1. Fastcgiなどのライブラリへの依存関係は必要ありません。
  2. モジュール内でnginxのすべての機能を使用できます。
12
Vivek Goel

ここではだれも実際の質問に対処したようには見えませんが、いくつかの素晴らしい回避策が提供されています。いくつかの小さな変更を加えて、nginx用のC++モジュールを構築できました。

  1. モジュールのソースファイル名を.cppで終わるように変更して、gccがC++を処理していることを認識できるようにします。
  2. すべてのnginxインクルード(ngx_config.h、ngx_core.hなど)がextern "C" {}構造でラップされていることを確認してください。同様に、nginx関数ポインターを介して呼び出されるすべての関数がラッパーで宣言されていることを確認してください。
  3. Nginxをセットアップするときに、「configure」呼び出しに--with-ld-opt = "-lstdc ++"を追加します。

これらの3つのステップで、モジュールはコンパイル、ビルド、リンクされ、実際に機能するはずです。

18

あなたが求めているのは、基本的には、データ構造を保持するc ++プロセスをWebサーバーに変換する方法です。それはそれについて行く最善の方法ではないかもしれません。 (そして、それはおそらくあなたの状況にあります。それは、あなたが推測しようとしているc ++プロセスのインターフェースの複雑さに依存します。)

とにかく、私は小さなhttpフロントエンドをc ++プロセスとクライアントの間に固定して、httpの作業を行い、 ZeroMQ/zmq のような単純なメッセージングプロトコルを使用してc ++バックエンドプロセスと通信できるようにします。

zmq in c/c ++はかなり単純で、非常に効率的で高速です。 zmqを使用すると、Python、または zmq bindings を使用する任意の言語でシンプルなウェブサーバーフロントエンドを非常にすばやくセットアップでき、そのフロントエンドにzmqを使用してバックエンドC++プロセスと非同期または同期で通信させることができます。

c ++の例the guide は、zmqの使用を検討している場合の良い出発点です。

Node.jsには いくつかの例 もあります。

10
Kimmeh

G-WANをお試しください。C++アプリケーションを直接使用できます。

4
Peter

あなたは試すことができます nginx c function

使い方は簡単で、アプリ層にnginxキャッシュメモリが組み込まれています wiki for nginx c function

cppを使用したサンプルプロジェクト

サンプルコード:

#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