Vivek Goel
Vivek Goel

Reputation: 24150

Best method to create a c++ app to communicate with nginx

I need to write a C++ interface that can read our data structure and provide the o/p based on query using http protocol.

Server Need
It should be able to serve 100 clients at the same time.

Why C++
All code is already written in C++. So we need to just write a http layer in C++. That's why I am choosing C++ instead of a more conventional web-programming language.

I am thinking to use nginx to serve static files and use its proxy pass to communicate with C++.

There are two approaches I have found:

Can you please list the pros and cons for each method based on prior experience?

Upvotes: 40

Views: 27800

Answers (6)

Christopher Smith
Christopher Smith

Reputation: 5542

No one here seems to have addressed the actual question, though some nice work arounds have been offered. I've been able to build C++ modules for nginx with a couple of minor changes.

  1. Change the module source file name to end with .cpp so gcc realizes it is dealing with C++.
  2. Make sure all your Nginx includes (e.g. ngx_config.h, ngx_core.h, etc.) are wrapped with an extern "C" { } structure. Similarly make sure any functions called through Nginx function pointers are declared with a wrapper.
  3. Add --with-ld-opt="-lstdc++" to your "configure" invocation when setting up Nginx.

With those three steps your module should compile, build, link, and actually work.

Upvotes: 20

CaptainCodeman
CaptainCodeman

Reputation: 2201

Just add an HTTP frontend to your C++ code, possibly using a library such as Beast, and then proxy_pass from nginx to your C++ server. You may or may not need nginx at all, depending on your use.

Upvotes: 0

Oktaheta
Oktaheta

Reputation: 626

You may try nginx c function

It is simple to use and built in nginx cache memory on apps layer, wiki for nginx c function

Example project with cpp

Sample 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;
}

Upvotes: 1

Peter
Peter

Reputation: 77

Try G-WAN, it allows you to use your c++ application directly.

Upvotes: 5

Vivek Goel
Vivek Goel

Reputation: 24150

I think I will go forward with Nginx module devlopment http://www.evanmiller.org/nginx-modules-guide.html

Why ?

  1. It don't require any other library dependency like fastcgi and other.
  2. I can use all feature of nginx inside my module.

Upvotes: 14

Kimmeh
Kimmeh

Reputation: 1011

What you are asking is basically how to turn the c++ process that holds your data strutures into a webserver. That might not be the best way to go about it. (Then again, maybe it is in your situation. It depends on the complexity of the c++ process's interfaces you are trying to expose i guess.)

Anyways, I would try to stick a small http frontend in between the c++ process and the clients that could do the http work and communicate with the c++ backend process using some simple messaging protocol like ZeroMQ/zmq.

zmq in c/c++ is fairly straight forward, and its very efficient and very fast. Using zmq you could very quickly setup a simple webserver frontend in python, or whatever language you prefer that has zmq bindings, and have that frontend communicate asyncronously or syncronously with the backend c++ process using zmq.

The c++ examples and the guide are nice starting points if you are looking into using zmq.

For Node.js there are also a few examples.

Upvotes: 11

Related Questions