it-swarm-eu.dev

Lze C ++ použít jako jazyk pro vývoj webových stránek na straně serveru?

Chtěl bych se dostat do vývoje webu pomocí C++ jako „skriptovacího jazyka“ na straně serveru. Moje serverová infrastruktura je založena na * nix, takže vývoj webových aplikací v C++ na Azure není aplikovatelný a C++/CLI ASP.NET také není použitelný.

Lze oddělit od starších aplikací CGI, lze vývoj webových aplikací provádět pomocí C++?

34
Scott Davies

Absolutně.

Existuje dokonce několik rámců pro jejich vývoj, včetně Wt , cppcms , CSP a dalších. Hlavní implementace FastCGI je v C a přímo podporuje několik jazyků , včetně C++.

V CGI nebo servletu lze použít jakýkoli programovací jazyk, který dokáže analyzovat řetězce. K vývoji modulů pro servery kompatibilní s ISAPI nebo Apache lze také použít jakýkoli jazyk, který dokáže implementovat vazby s knihovnami C.

Není to zvlášť snadné v C++ a dobré templářské motory jsou mezi sebou málo a daleko, ale lze to udělat.

Otázka, zda je to dobrý nápad, je samozřejmě zcela jiná záležitost. :)

Poznamenejte si: Hlavní webové stránky jako Amazon.com, eBay a Google používají C++ pro části své infrastruktury. Uvědomte si však, že Google používá C++ pouze pro systémy kritické pro rychlost a Amazon.com se relativně nedávno od LISP vzdálil (což rozhněvalo některé z jejich vyšších zaměstnanců :).

Facebook dříve kompiloval PHP do C++, ale jejich kompilátor HipHop (psaný částečně v C++) byl od té doby znovu vytvořen jako virtuální stroj s bajtovým kódem.

56
greyfade

Proč ne?

Seznamovací server OkCupid je vytvořen pomocí C++. Pravděpodobně existují další příklady.

K dispozici je také Qt-inspirovaná sada nástrojů pro vývoj webových aplikací s C++ s názvem Wt .

18
Vitor Py

Pokud plánujete napsat svou webovou aplikaci v C++, bylo by naprosté plýtvání s jejím propojením jako CGI.

Mým návrhem by bylo vytvořit asynchronní pomocí ASIO (asynchronní I/O). Díky tomu si můžete vytvořit rychlou webovou službu, která se vám líbí (v kombinaci s nginx jako reverzní proxy a serverem statics pro dosažení nejlepších efektů); Zkombinujte to s knihovnou šablon jako Wt a jste připraveni obsloužit desítky tisíc požadavků za sekundu z jediného serveru.

Další otázkou je, zda se jedná o praktickou alternativu k webovému rámci dynamického jazyka.

11
vartec

Krátká odpověď zní: Kdokoli lze použít k napsání webové stránky za předpokladu, že dokáže číst vstup, zapisovat interpretovatelný výstup a je spustitelná webovým serverem.

Technicky lze jakýkoli jazyk použít jako skript CGI za předpokladu, že:

  1. Interpretuje všechny vstupy a prostředí prezentované serverem
  2. Výstupy ve známém značkovacím jazyce (obvykle html)
  3. Může být spuštěn serverem

Existují také jiné způsoby. Perl má schopnost být vytvořen jako obal kolem kódu c/c ++, který funguje jako interpretační vrstva mezi těmito dvěma (a to nezahrnuje moduly Perl, které jsou vyrovnány kompilovány jako C).

9
Avatar_Squadron

na začátku to bylo celkem běžné - první webové stránky, na kterých jsem koncem 90. let pracoval, byly rozšíření ISAPI napsaná v jazyce C++ a fungovaly celkem dobře.

7
Steven A. Lowe

Zdá se, že Microsoft si to také myslí. Podívejte se na Casablanca což je nová sada nástrojů pro (zdá se) Azure pomocí C++.

Casablanca je projekt, který začíná zkoumat, jak nejlépe podporovat vývojáře C++, kteří chtějí využít radikální posun v softwarové architektuře, který cloud computing představuje.

Zde je přehled toho, co získáte u společnosti Casablanca:

  • Podpora přístupu REST služby z nativního kódu ve Windows Vista, Windows 7 a Windows 8 Consumer Preview poskytováním asynchronních vazeb C++ pro HTTP, JSON a URI)
  • Rozšíření sady Visual Studio SDK, které vám pomůže psát kód C++ HTTP na straně klienta v aplikaci Windows 8 Metro
  • Podpora psaní nativního kódu REST pro Azure, včetně integrace Visual Studio)
  • Pohodlné knihovny pro přístup k Azure blob a frontám od nativních klientů jako prvotřídní funkce Platforma jako služba (PaaS)
  • Konzistentní a výkonný model pro sestavování asynchronních operací založených na vlastnostech C++ 11
  • C++ implementace programovacího modelu založeného na herci Erlang
  • Sada vzorků a dokumentace
5
gbjbaanb

Pro PHP můžete napsat vlastní rozšíření C/C++ a získat tak dobré výhody pro výkon. Kdybych měl webovou aplikaci opravdu náročnou na CPU, pravděpodobně bych vytvořte malou knihovnu C++, která přenesla toto zpracování na rozšíření a pak vrátila výsledek zpět na PHP a potom PHP) výstupy do prohlížeče.

Další věcí, kterou lidé často neuvažují, je přemístění určitých procesorových procesů na straně klienta, např. JavaScript/jQuery. Pokud mám webový server, možná budu potřebovat procesor 3Ghz, aby mohl zpracovat náročné procesory pro konkrétní funkci (možná nějaké zpracování dat). Moje společnost platí každý měsíc peníze za tento server, aby zůstala v provozu. Pokud chci rozšířit operace na 100 souběžných uživatelů, kteří současně provozují tento úkol náročný na CPU, možná potřebuji více procesorů a serverů, což zvyšuje náklady pro mé podnikání. Pokud přenesu tuto náročnou úlohu CPU na stranu klienta, pak každý uživatel, který navštíví webovou stránku, může provést vlastní zpracování dat a nemusím zvyšovat schopnost serveru, čímž mi šetří peníze.

Koneckonců se všemi, s kolektivní výkonností 100+ stolních počítačů/tabletů/mobilních telefonů provádějících zpracování za vás, je to mnohem více energie než váš server, který sedí v datovém centru někde, kde každý měsíc stojí vaše obchodní peníze, aby zůstaly v provozu. Potenciálně by pak celý váš server dělal načítání dat z databáze, poskytování obsahu a kousek před/po zpracování a ověření dat před uložením zpět do databáze. Je zřejmé, že byste příliš nezvýšili CPU kód na straně klienta, což by mohlo blokovat/zmrazit uživatelské rozhraní webového prohlížeče, můžete vypálit požadavek AJAX požadavek na server, načíst data a poté zpracovat data asynchronně na straně klienta, takže uživatelské rozhraní webového prohlížeče je zcela použitelné.

2
zuallauz

Ano, lze jej použít. Ostatní zmínili různé přístupy. Tady je můj vlastní přístup. Výhodou je, že je zcela přenosný a samostatný, všechny vybrané knihovny závisí pouze na ANSI C. Nastavení vyžaduje pouze linuxové jádro a kompilátor C (A zjevné věci jako Busybox, bash atd.) (Nebo Windows a kompilátor), nejsou potřeba žádné další knihovny, žádné fantastické obrovské instalace.

Výsledkem je jediný program, který je jak webovým serverem, tak dynamickým generátorem stránek (nahrazuje „Apache“ i „php“), bude mít také přístup k databázi prostřednictvím sqlite.

Použité knihovny:

  • Mongoose - server Http
  • Sqlite - databáze SQL
  • MiniXML - Usnadňuje dynamické generování stránky. něco jako Javascript's createElement

Zbytek této odpovědi je kompletní průvodce nastavením pro Linux. SQlite i MiniXML jsou volitelné, ale průvodce pokrývá celou instalaci. Pokud máte zájem zakázat sqlite nebo MiniXML, je na vás, abyste okomentovali nepotřebné části.

1. Stáhněte si 3 knihovny

2. Připravte si složku

  • Vytvořte prázdnou složku (nazveme ji hlavní složkou)
  • Vložte do něj následující soubory:
    • Z sqlite tar.gz: sqlite3.c , sqlite3.h
    • Z Mongoose Zip: mongoose.c , mongoose.h
    • Z mxml tar.gz: mxml.h

3. Kompilace mxml

Možná jste si všimli, že mxml.c chybí, je to proto, že musíme vytvořit statickou knihovnu mxml. Přejděte do složky, kde byl stažen soubor mxml tar.gz, a proveďte:

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.

Po dokončení kompilace bude vygenerováno mnoho souborů, jediný soubor, který nás zajímá, je libmxml.a, zkopírujte tento soubor do hlavní složky.

3.1 Doublecheck

Zkontrolujte, zda hlavní složka obsahuje následující položky:

  • Pro mongoose: mongoose.c, mongoose.h
  • Pro mxml: libmxml.a, mxml.h
  • pro sqlite: sqlite.c, sqlite.h

4. main.c

Vytvořme skutečný program, vytvoříme main.c soubor v hlavní složce, zde je kostra, abyste mohli začít.

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

Nakonec kompilace!

Zkompilujme se. cd do vaší hlavní složky a proveďte tyto:

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 . 

Nyní spusťte server.out pomocí /server.out a přejděte na localhost:8080/hello

Hotovo :)

2
Hello World

Myslím, že několik vestavěných systémů (např. Směrovače, tiskárny, ...) má nějaký webový server řízený C++.

Zejména byste mohli použít nějakou knihovnu HTTP serverů, jako je libonion , přidat některé webové funkce do některého programu C nebo C++ nebo vyvinout světelný server s nějakým webovým rozhraním.

Někteří lidé kódují svůj webový server nebo své rozhraní HTTP v Ocaml pomocí Ocsigen . Ne každá webová věc je PHP. A s FastCGI můžete provést nějaké dynamické zpracování webu v/do vaší aplikace.