Bisakah C ++ digunakan sebagai bahasa pengembangan web sisi server? [Tutup]

34

Saya ingin masuk ke pengembangan web menggunakan C ++ sebagai "bahasa scripting" di sisi server. Infrastruktur server saya berbasis * nix, jadi melakukan pengembangan web di C ++ pada Azure tidak berlaku dan C ++ / CLI ASP.NET juga tidak berlaku.

Terpisah dari aplikasi CGI lama, dapatkah pengembangan web dilakukan menggunakan C ++?

Scott Davies
sumber
33
Tentu saja mungkin , pertanyaannya adalah; apakah ini praktis ?
Ed S.
Lihat pertanyaan ini di stackoverflow.com.
kevin cline
24
Anda bisa menggunakan rakitan sebagai bahasa sisi server jika Anda memang cenderung.
Channel72
8
Atau bahkan Brainf * ck jika ,yang .diarahkan ke soket.
dan04
4
Ini membawa kembali kenangan mengerikan tentang proyek web pertama yang saya ikuti. Gerbang CGI ke kode C. Aku masih bergidik ketika memikirkannya! :-)
Brian Knoblauch

Jawaban:

56

Benar.

Bahkan ada beberapa kerangka kerja untuk mengembangkannya, termasuk Wt , cppcms , CSP , dan lainnya. Implementasi utama FastCGI adalah dalam bahasa C, dan secara langsung mendukung beberapa bahasa , termasuk C ++.

Bahasa pemrograman apa pun yang dapat mengurai string dapat digunakan dalam CGI atau servlet. Bahasa apa pun yang dapat menerapkan binding dengan pustaka C juga dapat digunakan untuk mengembangkan modul untuk server yang kompatibel dengan ISAPI atau Apache.

Ini tidak terlalu mudah di C ++, dan mesin templating yang baik sedikit dan jarang, tetapi bisa dilakukan.

Tentu saja, pertanyaan apakah ini ide yang bagus adalah masalah lain. :)

Perhatikan: Situs web utama seperti Amazon.com, eBay, dan Google menggunakan C ++ untuk sebagian infrastrukturnya. Namun, sadari bahwa Google hanya menggunakan C ++ untuk sistem kecepatan kritis, dan Amazon.com relatif baru saja beralih dari Lisp (yang membuat marah beberapa staf senior mereka :).

Facebook sebelumnya mengkompilasi PHP ke C ++, tetapi kompiler HipHop mereka (sebagian ditulis dalam C ++) sejak itu telah diperhalus sebagai mesin virtual bytecode.

greyfade
sumber
2
+1 Untuk mengutip berbagai kerangka kerja. Anda harus menambahkan bahwa itu umum untuk (sangat) aplikasi web besar untuk didukung oleh c ++ (dan bahasa lainnya): amazon.com, google.com, sekarang facebook.com melalui hiphop, dll.
Klaim
7
@Klaim: Sudah biasa, tapi itu tidak berarti aturannya. Arsitektur Amazon secara historis berbasis Lisp dan hanya baru-baru ini ditulis ulang dalam C ++. Arsitektur Google melibatkan Java, Python, dan lainnya hampir sesering C ++, semuanya karena berbagai alasan. Facebook hanya menggunakan hiphop sekarang karena mereka tahu PHP tidak berskala. :)
greyfade
4
Saya setuju, tapi saya maksudkan bahwa itu masih merupakan contoh penggunaan C ++ yang terkenal - untuk menjawab langsung pertanyaan awal.
Klaim
1
@johannes Masalah penskalaan Facebook berasal dari fakta bahwa mereka harus mempertahankan urutan server yang lebih besar daripada yang diperlukan, khususnya karena buruknya kinerja skrip PHP yang dioptimalkan. Penskalaan linear tidak cukup baik untuk infrastruktur besar. Tetapi ingat bahwa pendekatan "tidak berbagi apa pun" tidak eksklusif untuk PHP. C dan C ++ dapat melakukannya juga.
greyfade
1
@amar Masalahnya adalah ada sedikit pengembalian kecuali dalam 0,1% aplikasi yang membutuhkan kinerja mentah. Anda dapat melayani dalam 1/3 waktu di sebagian besar bahasa lain dengan dukungan tumpukan web yang bagus. Bank, pengiklan web, dll. Semuanya melayani skala besar tanpa menggunakan C ++. Bahkan Facebook. Kericau. StackOverflow. Semua melakukannya dalam bahasa tingkat yang lebih tinggi. Di sini untuk tinggal tetapi tidak akan menjadi mayoritas lagi. Mungkin pernah.
Rig
18

Kenapa tidak?

Situs kencan OkCupid dibuat dengan C ++. Mungkin ada contoh lain.

Ada juga toolkit yang terinspirasi Qt untuk mengembangkan aplikasi web dengan C ++ yang disebut Wt .

Vitor Py
sumber
11
"Kenapa tidak "? Karena jauh lebih mudah menggunakan bahasa yang memiliki lebih banyak dukungan untuk hal semacam ini.
Ed S.
5
@ Ed S. Seperti yang saya dan greyfade tunjukkan ada kerangka kerja untuk mengembangkan aplikasi web dengan C ++.
Vitor Py
2
Ya, tapi sekali lagi, apakah mereka mudah digunakan seperti kerangka kerja yang lebih umum digunakan? Sejujurnya saya bertanya, saya bukan pengembang web dan saya belum pernah menggunakannya, tetapi ada sesuatu yang memberitahu saya bahwa mereka mungkin tidak matang atau banyak digunakan seperti (misalnya) rekan ruby ​​/ python / PHP.
Ed S.
3
@ Edit: Baik Ruby maupun Python tidak dimulai dengan kerangka kerja web. Bahkan butuh satu dekade bagi mereka untuk muncul. Kerangka kerja adalah konsekuensi belaka dari cukup banyak orang yang ingin menggunakan bahasa X untuk masalah Y. Hal yang sama bisa terjadi untuk C ++. Alasan utama mengapa tidak: C ++ tidak dikelola, butuh waktu lama untuk dikompilasi dan memiliki penghalang masuk yang lebih tinggi secara umum.
back2dos
1
@ back2dos: Siapa bilang kedua bahasa dikembangkan dengan mempertimbangkan web? Tentu saja tidak. Saya menggunakan istilah "dukungan".
Ed S.
11

Jika Anda berencana untuk menulis aplikasi web Anda dalam C ++, akan sia-sia total untuk kemudian antarmuka sebagai CGI.

Saran saya adalah membangunnya asinkron menggunakan ASIO (Asynchronous I / O). Dengan itu Anda dapat membangun layanan web cepat (gabungkan dengan nginx sebagai server reverse-proxy dan statika untuk efek terbaik); Gabungkan dengan pustaka template seperti Wt dan Anda siap melayani puluhan ribu permintaan per detik dari satu server.

Apakah ini merupakan alternatif praktis untuk kerangka kerja bahasa dinamis adalah masalah lain.

vartec
sumber
9

Jawaban singkatnya adalah, APA SAJA dapat digunakan untuk menulis halaman web asalkan dapat membaca input, menulis output yang dapat ditafsirkan, dan dapat dieksekusi oleh server web.

Secara teknis, bahasa apa pun dapat digunakan sebagai skrip CGI asalkan:

  1. Menafsirkan semua input dan lingkungan seperti yang disajikan oleh server
  2. Keluaran dalam bahasa markup yang dikenal (umumnya html)
  3. Dapat dijalankan oleh server

Ada juga cara lain juga. Perl memiliki kemampuan untuk dibangun sebagai pembungkus di sekitar kode c / c ++, bertindak sebagai lapisan penafsiran di antara keduanya (dan ini tidak termasuk modul perl yang flat out dikompilasi sebagai C).

Avatar_Squadron
sumber
7

pada awalnya, itu cukup umum - situs web pertama yang saya kerjakan pada akhir 1990-an adalah ekstensi ISAPI yang ditulis dalam C ++, dan mereka bekerja dengan cukup baik.

Steven A. Lowe
sumber
3
isapi.dll siapa saja?
red-dirt
atau ATLServer - atlserver.codeplex.com
gbjbaanb
5

Tampaknya Microsoft juga berpikir demikian. Lihat Casablanca yang merupakan seperangkat alat baru untuk (tampaknya) Azure menggunakan C ++.

Casablanca adalah proyek untuk mulai mengeksplorasi cara terbaik mendukung pengembang C ++ yang ingin mengambil keuntungan dari perubahan radikal dalam arsitektur perangkat lunak yang diwakili oleh komputasi awan.

Inilah yang Anda dapatkan dari Casablanca:

  • Dukungan untuk mengakses layanan REST dari kode asli pada Windows Vista, Windows 7, dan Windows 8 Consumer Preview dengan menyediakan ikatan C ++ yang tidak sinkron ke HTTP, JSON, dan URI
  • SDK ekstensi Visual Studio untuk membantu Anda menulis kode sisi klien C ++ HTTP di aplikasi Windows 8 Metro style Anda
  • Dukungan untuk menulis kode asli REST untuk Azure, termasuk integrasi Visual Studio
  • Perpustakaan yang nyaman untuk mengakses Azure blob dan penyimpanan antrian dari klien asli sebagai fitur Platform-as-a-Service (PaaS) kelas satu
  • Model yang konsisten dan kuat untuk menyusun operasi asinkron berdasarkan fitur C ++ 11
  • Implementasi C ++ dari model pemrograman berbasis aktor Erlang
  • Satu set sampel dan dokumentasi
gbjbaanb
sumber
2

Untuk PHP Anda dapat menulis ekstensi C / C ++ Anda sendiri dan mendapatkan manfaat kinerja yang baik seperti itu. Jika saya memiliki bagian intensif CPU dari aplikasi web saya, saya mungkin akan membuat perpustakaan C ++ kecil yang membongkar pemrosesan itu ke ekstensi dan kemudian mengembalikan hasilnya kembali ke PHP dan kemudian PHP output ke browser.

Hal lain yang orang tidak sering pertimbangkan adalah membongkar pemrosesan CPU tertentu ke sisi klien misalnya JavaScript / jQuery. Jika saya punya server web, saya mungkin memerlukan CPU 3Ghz untuk melakukan pemrosesan intensif CPU untuk fungsi tertentu (mungkin beberapa pemrosesan data). Perusahaan saya membayar uang untuk server itu setiap bulan agar tetap berjalan. Jika saya ingin meningkatkan operasi untuk 100 pengguna bersamaan yang menjalankan tugas intensif CPU pada saat yang sama, maka mungkin saya perlu beberapa CPU dan server, meningkatkan biaya untuk bisnis saya. Jika saya melepas tugas intensif CPU ke sisi klien, maka setiap pengguna yang mengunjungi situs web dapat melakukan pemrosesan sendiri pada data dan saya tidak perlu meningkatkan kemampuan server saya sehingga menghemat uang.

Setelah semua dengan semua kekuatan kolektif 100+ desktop / tablet / ponsel melakukan pemrosesan untuk Anda, itu jauh lebih banyak kekuatan daripada server Anda duduk di pusat data di suatu tempat menghabiskan uang bisnis Anda setiap bulan untuk terus berjalan. Berpotensi maka semua server Anda akan melakukan akan mengambil data dari database, melayani konten dan sedikit pemrosesan pra / post dan validasi data sebelum menyimpan kembali dalam database. Jelas Anda tidak akan membuat kode sisi klien terlalu intensif CPU yang dapat memblokir / membekukan UI browser web, Anda dapat menjalankan permintaan AJAX ke server, mengambil data dan kemudian memproses data secara asinkron sisi klien, meninggalkan web -browser UI sepenuhnya dapat digunakan.

zuallauz
sumber
2

Ya, itu bisa digunakan. Yang lain telah menyebutkan berbagai pendekatan. Ini pendekatan saya sendiri. Keuntungannya adalah ini benar-benar portabel dan mandiri, semua perpustakaan yang dipilih hanya bergantung pada ANSI C. Pengaturannya hanya membutuhkan Kernel Linux dan kompiler C (Dan hal-hal yang jelas seperti Busybox, bash, dll) (atau Windows dan kompiler), tidak ada perpustakaan tambahan yang diperlukan, tidak ada instalasi besar yang mewah.

Hasilnya adalah sebuah program tunggal yang merupakan server web dan generator halaman dinamis (Mengganti "apache" dan "php"), itu juga akan memiliki akses database melalui sqlite.

Perpustakaan yang digunakan:

  • Mongoose - Server Http
  • Sqlite - Database SQL
  • MiniXML - Membuat pembuatan halaman dinamis lebih mudah. semacam seperti JavascriptcreateElement

Sisa dari jawaban ini adalah panduan pengaturan lengkap untuk Linux. Baik SQlite dan MiniXML adalah opsional, tetapi panduan ini mencakup instalasi lengkap. Terserah Anda untuk mengomentari bagian yang tidak diperlukan jika Anda tertarik untuk menonaktifkan sqlite atau MiniXML.

1. Unduh 3 perpustakaan

2. Siapkan folder Anda

  • Buat folder kosong (Kami akan menyebutnya folder utama)
  • Masukkan file-file berikut ke dalamnya:
    • Dari sqlite tar.gz: sqlite3.c , sqlite3.h
    • Dari zip Mongoose: mongoose.c , mongoose.h
    • Dari mxml tar.gz: mxml.h

3. Kompilasi mxml

Anda mungkin telah memperhatikan bahwa mxml.c tidak ada, ini karena kami perlu membuat perpustakaan mxml statis. Buka folder tempat mxml tar.gz diunduh dan lakukan:

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.

Setelah kompilasi selesai, banyak file akan dihasilkan, satu-satunya file yang menarik bagi kami adalah libmxml.a, salin file itu ke folder utama.

3.1 Doublecheck

Periksa apakah folder utama memiliki yang berikut:

  • Untuk luwak: mongoose.c, mongoose.h
  • Untuk mxml: libmxml.a, mxml.h
  • untuk sqlite: sqlite.c, sqlite.h

4. main.c

Mari kita buat program yang sebenarnya, buat main.cfile di folder utama, di sini ada kerangka untuk Anda mulai.

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

Akhirnya, kompilasi!

Mari kita kompilasi. cdke folder utama Anda dan jalankan ini:

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 . 

Sekarang, jalankan server.out dengan /server.out, dan navigasikan kelocalhost:8080/hello

Selesai :)

Halo Dunia
sumber
@ Hei: Terima kasih telah menunjukkan alternatif luwak ini, saya selalu lebih suka proyek berbasis masyarakat. Saya mungkin akan mengganti Mongoose dengan Civetweb dalam jawaban saya setelah saya mengujinya secara menyeluruh.
Hello World
0

Saya kira beberapa sistem tertanam (mis. Router, printer, ...) memiliki beberapa server web yang digerakkan C ++.

Secara khusus, Anda dapat menggunakan beberapa pustaka server HTTP seperti libonion untuk menambahkan beberapa kemampuan web ke beberapa program C atau C ++, atau untuk mengembangkan server yang ringan dengan beberapa antarmuka web.

Beberapa orang sedang mengkode server Web mereka atau antarmuka HTTP mereka di Ocaml menggunakan Ocsigen . Tidak semua web adalah PHP. Dan dengan FastCGI Anda dapat memproses web dinamis di / ke aplikasi Anda.

Basile Starynkevitch
sumber