Il C ++ può essere utilizzato come linguaggio di sviluppo Web sul lato server? [chiuso]


34

Mi piacerebbe entrare nello sviluppo web usando C ++ come "linguaggio di scripting" sul lato server. La mia infrastruttura server è basata su * nix, quindi lo sviluppo Web in C ++ su Azure non è applicabile e anche ASP.NET C ++ / CLI non è applicabile.

Separato dalle applicazioni CGI legacy, lo sviluppo Web può essere eseguito utilizzando C ++?


33
Naturalmente è possibile , la domanda è; è pratico ?
Ed S.

Vedi questa domanda su stackoverflow.com.
Kevin Cline

24
È possibile utilizzare assembly come lingua lato server se si fosse così propensi.
Channel72

8
O anche Brainf * ck se ,si .viene reindirizzati ad una presa di corrente.
dan04

4
Questo riporta ricordi orribili del primo progetto web in cui sono stato coinvolto. Gateway CGI al codice C. Rabbrividisco ancora quando ci penso! :-)
Brian Knoblauch

Risposte:


56

Assolutamente.

Esistono anche diversi framework per svilupparli, inclusi Wt , cppcms , CSP e altri. L'implementazione della linea principale di FastCGI è in C e supporta direttamente diverse lingue , incluso C ++.

Qualsiasi linguaggio di programmazione in grado di analizzare le stringhe può essere utilizzato in CGI o in un servlet. Qualsiasi linguaggio in grado di implementare associazioni con librerie C può anche essere usato per sviluppare moduli per server compatibili ISAPI o Apache.

Non è particolarmente facile in C ++ e i buoni motori di template sono pochi e distanti tra loro, ma può essere fatto.

Naturalmente, la questione se questa sia una buona idea è completamente un'altra questione. :)

Nota: i principali siti Web come Amazon.com, eBay e Google utilizzano C ++ per parti della loro infrastruttura. Renditi conto, tuttavia, che Google utilizza il C ++ solo per sistemi critici per la velocità e che Amazon.com è passato relativamente di recente da Lisp (il che ha fatto arrabbiare parte del suo staff senior :).

Facebook ha precedentemente compilato PHP in C ++, ma il loro compilatore HipHop (scritto in parte in C ++) da allora è stato riprogettato come una macchina virtuale bytecode.


2
+1 Per citare vari quadri. Dovresti aggiungere che è comune che le (molto) grandi app web siano alimentate da c ++ (e altre lingue): amazon.com, google.com, ora facebook.com tramite hiphop, ecc.
Klaim

7
@Klaim: è comune, ma non è affatto la regola. L'architettura di Amazon era storicamente basata su Lisp e solo di recente riscritta in C ++. L'architettura di Google coinvolge Java, Python e altri quasi quanto il C ++, il tutto per vari motivi. Facebook utilizza l'hiphop solo ora perché hanno scoperto che PHP non si ridimensiona. :)
greyfade il

4
Sono d'accordo, ma intendevo dire che sono ancora esempi ben noti di utilizzo del C ++, per rispondere direttamente al titolo della domanda originale.
Klaim

1
@johannes Il problema del ridimensionamento di Facebook deriva dal fatto che devono mantenere un ordine di grandezza più server di quanto sia altrimenti necessario, in particolare a causa delle scarse prestazioni di uno script PHP ottimizzato. Il ridimensionamento lineare semplicemente non è abbastanza buono per un'infrastruttura così grande. Ma ricorda che l'approccio "nulla condiviso" non è esclusivo di PHP. Anche C e C ++ possono farlo.
Greyfade,

1
@amar Il fatto è che c'è poco ritorno tranne nello 0,1% delle app che necessitano di prestazioni non elaborate. Potresti servire in 1/3 del tempo nella maggior parte delle altre lingue con un buon supporto dello stack web. Banche, inserzionisti web, ecc. Servono tutti su vasta scala senza ricorrere al C ++. Anche Facebook. Twitter. StackOverflow. Tutti lo fanno in lingue di livello superiore. È qui per rimanere, ma non diventerà di nuovo la maggioranza. Probabilmente mai.
Rig

18

Perchè no?

Il sito di incontri OkCupid è stato creato con C ++. Probabilmente ci sono altri esempi.

C'è anche un toolkit ispirato a Qt per lo sviluppo di applicazioni Web con C ++ chiamato Wt .


11
"Perché no "? Perché è molto più facile usare un linguaggio che ha più supporto per questo genere di cose.
Ed S.

5
@Ed S. Come ho sottolineato io e greyfade, esistono framework per lo sviluppo di applicazioni Web con C ++.
Vitor Py

2
Sì, ma ancora una volta, sono facili da usare come i framework più comunemente usati? Sto chiedendo onestamente, non sono uno sviluppatore web e non li ho mai usati, ma qualcosa mi dice che probabilmente non sono così maturi o ampiamente usati come (ad esempio) le loro controparti ruby ​​/ python / PHP.
Ed S.

3
@EdS .: Né Ruby né Python hanno iniziato con i framework web. In effetti, ci sono voluti un decennio per apparire. I framework sono la semplice conseguenza di un numero sufficiente di persone che desiderano utilizzare il linguaggio X per il problema Y. Lo stesso potrebbe accadere per il C ++. Principali motivi per cui non lo ha fatto: il C ++ non è gestito, richiede tempi di compilazione e presenta una barriera d'ingresso più elevata in generale.
back2dos

1
@ back2dos: chi ha detto che entrambe le lingue sono state sviluppate pensando al web? Certamente no. Ho usato il termine "supporto".
Ed S.

11

Se stai pianificando di scrivere la tua applicazione web in C ++, sarebbe un totale spreco interfacciarlo come CGI.

Il mio suggerimento sarebbe di costruirlo in modo asincrono usando ASIO (Asincrono I / O). In questo modo puoi creare un servizio web estremamente veloce ( combinalo con nginx come proxy inverso e server statico per ottenere i migliori effetti); Combinalo con una libreria di modelli come Wt e sei pronto a servire decine di migliaia di richieste al secondo da un singolo server.

Se questa sia un'alternativa pratica al framework web linguistico dinamico è un altro problema.


9

La risposta breve è che TUTTO può essere usato per scrivere una pagina Web a condizione che possa leggere l'input, scrivere output interpretabile ed è eseguibile dal server web.

Tecnicamente, qualsiasi linguaggio può essere utilizzato come script CGI a condizione che:

  1. Interpreta tutti gli input e l'ambiente come presentati dal server
  2. Output in un linguaggio di markup noto (generalmente html)
  3. Può essere eseguito dal server

Ci sono anche altri modi. Perl ha la capacità di essere costruito come un wrapper attorno al codice c / c ++, fungendo da strato di interpretazione tra i due (e questo non include i moduli perl che vengono compilati come C).



5

Sembra che anche Microsoft pensi di poterlo fare. Dai un'occhiata a Casablanca, che è un nuovo set di strumenti per (sembra) Azure usando C ++.

Casablanca è un progetto per iniziare a esplorare come supportare al meglio gli sviluppatori C ++ che vogliono trarre vantaggio dal cambiamento radicale nell'architettura software rappresentata dal cloud computing.

Ecco cosa ottieni con Casablanca:

  • Supporto per l'accesso ai servizi REST da codice nativo su Windows Vista, Windows 7 e Windows 8 Consumer Preview fornendo collegamenti C ++ asincroni a HTTP, JSON e URI
  • Un SDK di estensione di Visual Studio per aiutarti a scrivere codice lato client HTTP C ++ nella tua app Metro 8 di Windows
  • Supporto per la scrittura di REST in codice nativo per Azure, inclusa l'integrazione di Visual Studio
  • Pratiche librerie per l'accesso all'archiviazione BLOB e code di Azure da client nativi come funzionalità PaaS (Platform-as-a-Service) di prima classe
  • Un modello coerente e potente per la composizione di operazioni asincrone basato sulle funzionalità di C ++ 11
  • Un'implementazione in C ++ del modello di programmazione basato sull'attore di Erlang
  • Una serie di campioni e documentazione

2

Per PHP puoi scrivere le tue estensioni C / C ++ e ottenere buoni benefici in questo modo. Se avessi avuto una parte davvero intensiva della CPU della mia applicazione web probabilmente avrei creato una piccola libreria C ++ che ha scaricato quell'elaborazione sull'estensione e quindi ha restituito il risultato al PHP e quindi il PHP lo ha inviato al browser.

L'altra cosa che la gente spesso non considera è scaricare una certa elaborazione della CPU sul lato client, ad esempio JavaScript / jQuery. Se ho un web server, potrei aver bisogno di una CPU a 3 GHz per eseguire un'elaborazione intensiva della CPU per una particolare funzione (forse un po 'di elaborazione dei dati). La mia azienda paga ogni mese per quel server per mantenerlo attivo. Se voglio aumentare le operazioni per 100 utenti simultanei che eseguono contemporaneamente l'attività intensiva della CPU, forse ho bisogno di più CPU e server, aumentando i costi per la mia attività. Se scarico quell'attività intensiva della CPU sul lato client, ogni utente che visita il sito Web può eseguire la propria elaborazione sui dati e non devo aumentare la capacità del mio server risparmiando così denaro.

Dopotutto con la potenza collettiva di oltre 100 desktop / tablet / cellulari che eseguono l'elaborazione per te, questo è molto più potente del tuo server seduto in un datacenter da qualche parte che costa ai tuoi soldi ogni mese per continuare a funzionare. Potenzialmente, tutto ciò che il tuo server farebbe sarebbe recuperare i dati dal database, servire il contenuto e un po 'di pre / post elaborazione e validazione dei dati prima di archiviarli nuovamente nel database. Ovviamente non dovresti rendere il codice lato client troppo intenso per la CPU che potrebbe bloccare / bloccare l'interfaccia utente del browser web, potresti lanciare una richiesta AJAX sul server, recuperare i dati e quindi elaborare i dati in modo asincrono sul lato client, lasciando il web -browser UI completamente utilizzabile.


2

Sì, può essere usato. Gli altri hanno menzionato vari approcci. Ecco il mio approccio. Il vantaggio è che è totalmente portatile e autonomo, tutte le librerie scelte dipendono solo da ANSI C. L'impostazione richiede solo il kernel Linux e un compilatore C (E le cose ovvie come Busybox, bash, ecc.) (O Windows e un compilatore), non sono necessarie librerie extra, nessuna grande installazione di fantasia.

Il risultato è un singolo programma che è sia un web server che un generatore di pagine dinamico (sostituisce sia "apache" che "php"), inoltre avrà accesso al database tramite sqlite.

Librerie utilizzate:

  • Mongoose - Server http
  • Sqlite - Database SQL
  • MiniXML - Semplifica la generazione di pagine dinamiche. un po 'come JavascriptcreateElement

Il resto di questa risposta è una guida di installazione completa per Linux. Sia SQlite che MiniXML sono opzionali, ma la guida copre l'installazione completa. Spetta a te commentare le parti non necessarie se sei interessato a disabilitare sqlite o MiniXML.

1. Scarica le 3 librerie

2. Prepara la tua cartella

  • Crea una cartella vuota (la chiameremo la cartella principale)
  • Inserisci i seguenti file:
    • Da sqlite tar.gz: sqlite3.c , sqlite3.h
    • Dalla zip Mongoose: mongoose.c , mongoose.h
    • Dal mxml tar.gz: mxml.h

3. Compila mxml

Potresti aver notato che manca mxml.c, questo perché abbiamo bisogno di creare una libreria mxml statica. Vai alla cartella in cui è stato scaricato mxml tar.gz ed esegui:

tar -xvf mxml-<version>.tar.gz #Extract the tar
cd mxml-<version> #Go to the newly extracted directory
./configure #prepare the compiler
make #compile, you may need to install "make" first.

Una volta terminata la compilazione, verranno generati molti file, l'unico file che ci interessa è libmxml.acopiarlo nella cartella principale.

3.1 Doppio controllo

Verificare che la cartella principale abbia quanto segue:

  • Per la mangusta: mongoose.c, mongoose.h
  • Per mxml: libmxml.a, mxml.h
  • per sqlite: sqlite.c, sqlite.h

4. main.c

Creiamo il programma attuale, creiamo un main.cfile nella cartella principale, ecco uno scheletro per iniziare.

#include <string.h>
#include <stdio.h>

#include "mongoose.h"
#include "mxml.h"
#include "sqlite3.h"

/***Sqlite initialization stuff***/
//comment out everything sqlite related if you don't want sqlite, including the callback function and the include "sqlite3.h"
static int callback(void * custom, int argc, char **argv, char **azColName);
char *zErrMsg = 0;
sqlite3 *db;
int rc;

/***Just some laziness shortcut functions I made***/
typedef mxml_node_t * dom; //type "dom" instead of "mxml_node_t *"
#define c mxmlNewElement   //type "c" instead of "mxmlNewElement"
inline void t(dom parent,const char *string) //etc
{
    mxmlNewText(parent, 0, string);
}

//type "sa" instead of "mxmlElementSetAttr"
inline void sa(dom element,const char * attribute,const char * value) 
{
    mxmlElementSetAttr(element,attribute,value);
}




//The only non boilerplate code around in this program is this function
void serve_hello_page(struct mg_connection *conn)
{
    char output[1000];
    mg_send_header(conn,"Content-Type","text/html; charset=utf-8");
    mg_printf_data(conn, "%s", "<!DOCTYPE html>");
    //This literally prints into the html document


    /*Let's generate some html, we could have avoided the
     * xml parser and just spat out pure html with mg_printf_data
     * e.g. mg_printF_data(conn,"%s", "<html>hello</html>") */

    //...But xml is cleaner, here we go:
            dom html=mxmlNewElement(MXML_NO_PARENT,"html");
                dom head=c(html,"head");
                    dom meta=c(head,"meta");
                    sa(meta,"charset","utf-8");
                dom body=c(html,"body");
                    t(body,"Hello, world<<"); //The < is auto escaped, neat!
                    c(body,"br");
                    t(body,"Fred ate bred");    
                dom table=c(body,"table");
                sa(table,"border","1");

                //populate the table via sqlite
                rc = sqlite3_exec(db, "SELECT * from myCoolTable", callback, table, &zErrMsg);
                if( rc!=SQLITE_OK )
                {
                    fprintf(stderr, "SQL error: %s\n", zErrMsg);
                    sqlite3_free(zErrMsg);
                }

            mxmlSaveString (html,output,1000,  MXML_NO_CALLBACK);
            mg_printf_data(conn, "%s", output);
            mxmlDelete(html); 
}

//sqlite callback
static int callback(void * custom, int argc, char **argv, char **azColName)
{
    //this function is executed for each row
    dom table=(dom)custom;

    dom tr=c(table,"tr");
    dom td;
    int i;
    for(i=0; i<argc; i++)
    {
        td=c(tr,"td");
        if (argv[i])
            t(td, argv[i]);
        else
            t(td, "NULL");

        printf("%s == %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
     printf("\n");
     return 0;
}


static int event_handler(struct mg_connection *conn, enum mg_event ev)
{
    if (ev == MG_AUTH)
    {
        return MG_TRUE;   // Authorize all requests
    }
    else if (ev == MG_REQUEST)
    {
        if (!strcmp(conn->uri, "/hello"))
        {
            serve_hello_page(conn);
            return MG_TRUE;   // Mark as processed
        }
    }
    return MG_FALSE;  // Rest of the events are not processed

}

int main(void)
{
    struct mg_server *server = mg_create_server(NULL, event_handler);
    //mg_set_option(server, "document_root", "."); //prevent dir listing and auto file serving
    //TODO can I allow file listing without dir listing in a specified directory?
    mg_set_option(server, "listening_port", "8080");


    rc = sqlite3_open("db.sqlite3", &db); 

    if( rc )
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return(1);
    }

    printf("Server is running on port 8080!\n");
    for (;;)
    {
        mg_poll_server(server, 1000);  // Infinite loop, Ctrl-C to stop
    }
    mg_destroy_server(&server);
    sqlite3_close(db);

    return 0;
}




/*
 * useful stuff:
 * mg_send_file(struct mg_connection *, const char *path); - serve the file at *path*/

Infine, compilando!

Compiliamo. cdnella tua cartella principale ed esegui questi:

gcc -c main.c
gcc -c mongoose.c
gcc -c sqlite3.c
gcc -o server.out main.o mongoose.o sqlite3.o -ldl -lpthread -lmxml -L . 

Ora esegui server.out con /server.oute vai alocalhost:8080/hello

Fatto :)



@Hey: Grazie per aver sottolineato questa alternativa Mongoose, preferisco sempre i progetti guidati dalla comunità. Probabilmente sostituirò Mongoose con Civetweb nella mia risposta dopo averlo testato a fondo.
Ciao World

0

Immagino che diversi sistemi embedded (ad es. Router, stampanti, ...) abbiano un web server guidato da C ++.

In particolare, è possibile utilizzare alcune librerie di server HTTP come libonion per aggiungere alcune funzionalità Web ad alcuni programmi C o C ++ o per sviluppare un server leggero con qualche interfaccia web.

Alcune persone stanno codificando il loro server Web o la loro interfaccia HTTP in Ocaml usando Ocsigen . Non ogni cosa web è PHP. E con FastCGI è possibile elaborare dinamicamente il Web nella / nella propria applicazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.