C ++ sunucu tarafı web geliştirme dili olarak kullanılabilir mi? [kapalı]


34

Sunucu tarafında "++ dili" olarak C ++ kullanarak web geliştirmeye geçmek istiyorum. Sunucu altyapım * nix tabanlıdır, bu yüzden Azure'da C ++ 'da web geliştirme yapmak geçerli değildir ve C ++ / CLI ASP.NET de uygulanabilir değildir.

Eski CGI uygulamalarından ayrı, web geliştirme C ++ kullanılarak yapılabilir mi?


33
Tabii ki mümkün , soru şu; öyle pratik ?
Ed S.

Stackoverflow.com adresinde bu soruya bakın .
kevin cl

24
Eğer eğimli olsaydınız montajı sunucu tarafı bir dil olarak kullanabilirsiniz.
Kanal72

8
Hatta Brainf * ck eğer ,edilir .bir sokete yönlendirilir.
dan04

4
Bu, katıldığım ilk web projesinin korkunç anılarını geri getiriyor. CGI, C koduna açılan kapılar. Düşündüğümde hala titriyorum! :-)
Brian Knoblauch

Yanıtlar:


56

Kesinlikle.

Bunları geliştirmek için çeşitli çerçeveler bile var Wt , cppcms , CSP ve diğerleri . FastCGI'ın ana hattı C dilinde ve doğrudan C ++ dahil birçok dili destekliyor .

Dizeleri ayrıştırabilen herhangi bir programlama dili, CGI veya sunucu uygulamasında kullanılabilir. ISAPI veya Apache uyumlu sunucular için modüller geliştirmek üzere C kütüphaneleriyle ciltleme uygulayabilen herhangi bir dil de kullanılabilir.

C ++ 'ta özellikle kolay değil ve iyi şablonlama motorları çok az ve çok uzak, ancak yapılabilir.

Elbette, bunun iyi bir fikir olup olmadığı sorusu tamamen başka bir konudur. :)

Not: Amazon.com, eBay ve Google gibi büyük web siteleri, altyapılarının parçaları için C ++ 'ı kullanır. Bununla birlikte, Google’ın yalnızca kritik öneme sahip sistemler için C ++ kullandığını ve Amazon.com’un nispeten yakın bir zamanda Lisp’ten (kıdemli çalışanlarının bazılarını kızdırdığını :) uzaklaştırdığını fark edin.

Facebook daha önce PHP'yi C ++ 'a derledi, ancak HipHop derleyicileri (kısmen C ++' da yazılmıştı) o zamandan beri bir bytecode sanal makinesi olarak düzeltildi.


2
+1 Çeşitli çerçevelerden alıntı yapmak için. C ++ (ve diğer dillerin) tarafından desteklenmekte olan (çok) büyük web uygulamaları için yaygın olduğunu eklemelisiniz: amazon.com, google.com, şimdi facebook.com hiphop aracılığıyla, vb.
Klaim

7
@Klaim: Yaygın, ancak hiçbir şekilde kural değildir. Amazon'un mimarisi tarihsel olarak Lisp'e dayanıyordu ve ancak yakın zamanda C ++ dilinde yeniden yazıldı. Google’ın mimarisi, çeşitli nedenlerle Java, Python ve diğerlerini neredeyse C ++ kadar sık ​​sık içeriyor. Facebook sadece hiphop kullanıyor çünkü PHP'nin ölçeklemediğini öğrendiler. :)
greyfade

4
Katılıyorum, ancak orjinal soru başlığını doğrudan cevaplamak için hala C ++ kullanımının iyi bilinen örnekleri olduklarını kastettim.
Klaim

1
@johannes Facebook'un ölçeklendirme problemi, özellikle optimize edilmiş bir PHP betiğinin düşük performansı nedeniyle, gerekenden daha fazla sunucuyu büyük olasılıkla gerekenden daha fazla sunucuda tutmaları gerekmesinden kaynaklanıyor. Doğrusal ölçeklendirme, böyle büyük bir altyapı için yeterli değildir. Ancak, "hiçbir şey paylaşılmadı" yaklaşımının PHP'ye özel olmadığını unutmayın. C ve C ++ da bunu yapabilir.
greyfade

1
@ Amacım, bu ham performansa ihtiyaç duyan uygulamaların% 0,1'i dışında çok az geri dönüş olması. İyi web yığını desteği ile çoğu dilde 1/3 oranında hizmet verebilirsiniz. Bankalar, web reklamverenleri vb. Hepsi C ++ 'a başvurmadan muazzam ölçeklerde hizmet vermektedir. Facebook bile. Heyecan. StackOverflow. Hepsi yüksek seviyeli dillerde. Onun burada kalması, ancak bir daha çoğunluğa dönüşmeyecek. Muhtemelen hiç.
Rig,

18

Neden olmasın?

OkCupid arkadaşlık sitesi C ++ ile oluşturulur. Muhtemelen başka örnekler de var.

Ayrıca Wt denilen C ++ ile web uygulamaları geliştirmek için Qt ilham alan bir araç seti de var .


11
"Neden olmasın "? Çünkü bu tür şeyler için daha fazla desteği olan bir dili kullanmak çok daha kolay.
Ed S.

5
@ Ed S. Ben ve greyfade'nin işaret ettiği gibi, C ++ ile web uygulamaları geliştirmek için çerçeveler var.
Vitor Py

2
Evet, fakat yine, daha çok kullanılan çerçeveler kadar kullanımı kolay mı? Gerçekten soruyorum, bir web geliştiricisi değilim ve onları hiç kullanmamıştım, ancak bir şey bana muhtemelen yakut / piton / PHP meslektaşları (örneğin) kadar olgun veya yaygın olarak kullanılmadıklarını söylüyor.
Ed S.

3
@EdS .: Ne Ruby ne de Python web çerçeveleriyle başladı. Aslında bunların ortaya çıkması on yıl sürdü. Bu çerçeveler, Y dili için X dilini kullanmak isteyen yeterli sayıda insanın sonucudur. Aynı şey C ++ için de olabilir. Başlamamasının ana nedenleri: C ++ yönetilmez, derlenmesi yaş alır ve genelde daha yüksek bir giriş engeline sahiptir.
back2dos

1
@ back2dos: Kim dilin web düşünülerek geliştirildiğini söyledi? Kesinlikle yapmadım. Ben "destek" terimini kullandım.
Ed S.

11

Web uygulamanızı C ++ ile yazmayı planlıyorsanız, daha sonra CGI olarak arabirim oluşturmak tam bir israf olacaktır.

Benim önerim kullanarak kullanarak zaman uyumsuz oluşturmak olacaktır ASIO (Asenkron I / O) . Bu sayede ışıltılı hızlı web servisi oluşturabilirsiniz ( en iyi efektler için nginx'i ters proxy ve statik sunucu olarak birleştirin ); Bunu Wt gibi şablon kütüphanesiyle birleştirin ve tek bir sunucudan saniyede onbinlerce istek sunmaya hazırsınız.

Bunun dinamik dil web çerçevesine pratik bir alternatif olup olmadığı bir başka konudur.


9

Kısa cevap, herhangi bir girişi okumak, yorumlanabilir çıktı yazmak ve web sunucusu tarafından çalıştırılabilmesi için bir web sayfası yazmak için herhangi bir şey kullanılabilir.

Teknik olarak, herhangi bir dil, bir CGI betiği olarak kullanılabilir:

  1. Sunucu tarafından sunulan tüm girdileri ve ortamı yorumlar.
  2. Bilinen bir biçimlendirme dilinde çıktılar (genellikle html)
  3. Sunucu tarafından çalıştırılabilir

Başka yolları da var. Perl, c / c ++ kodunun etrafına bir sarmalayıcı olarak inşa edilebilme kabiliyetine sahiptir, ikisi arasında bir yorumlayıcı katman görevi görür (ve bu, C olarak düzleştirilmiş perl modülleri içermez).



5

Görünüşe göre Microsoft da öyle düşünüyor. C ++ kullanarak Azure için yeni bir araç seti olan Casablanca'ya göz atın .

Casablanca, bulut bilişimin temsil ettiği yazılım mimarisindeki köklü değişiklikten yararlanmak isteyen C ++ geliştiricilerini en iyi şekilde nasıl destekleyeceğini araştırmaya başlayan bir proje.

Casablanca'dan aldığınız şey:

  • HTTP, JSON ve URI'lara zaman uyumsuz C ++ bağları sağlayarak Windows Vista, Windows 7 ve Windows 8 Tüketici Önizlemesinde yerel koddan REST hizmetlerine erişme desteği
  • Windows 8 Metro tarzı uygulamanıza C ++ HTTP istemcisi yan kodunu yazmanıza yardımcı olacak bir Visual Studio eklentisi SDK
  • Visual Studio entegrasyonu dahil olmak üzere Azure için yerel kod REST yazma desteği
  • Birinci sınıf bir Hizmet Olarak Platform (PaaS) özelliği olarak yerel istemcilerden Azure blob ve kuyruk deposuna erişmek için kullanışlı kütüphaneler
  • C ++ 11 özelliklerine göre zaman uyumsuz işlemleri oluşturmak için tutarlı ve güçlü bir model
  • Erlang aktör bazlı programlama modelinin C ++ uygulaması
  • Bir dizi örnek ve dokümantasyon

2

PHP için kendi C / C ++ eklentilerinizi yazabilir ve bu şekilde iyi performans avantajları elde edebilirsiniz. Web uygulamamın gerçekten yoğun bir işlemcisi olsaydı, muhtemelen bu işleme eklentiyi yükleyen ve sonucu PHP'ye geri döndüren küçük bir C ++ kütüphanesi yapardım ve ardından PHP tarayıcıya verir.

İnsanların sıklıkla göz önünde bulundurmadığı diğer bir şey ise bazı CPU işlemlerini müşteri tarafına boşaltmadır, örneğin JavaScript / jQuery. Bir web sunucum varsa, belirli bir işlev için CPU yoğun işlemesi yapabilmek için bir 3GHz CPU'ya ihtiyacım olabilir (belki bazı veri işleme). Şirketim her ay bu sunucuya çalışır durumda kalmak için para ödüyor. Aynı anda aynı CPU yoğunluğunu çalıştıran 100 kullanıcı için işlemleri büyütmek istersem, belki de işletme maliyetini artırarak birden fazla CPU ve sunucuya ihtiyacım var. Bu CPU yoğun görevini istemci tarafına boşaltırsam, web sitesini ziyaret eden her kullanıcı veri üzerinde kendi işlemlerini yapabilir ve sunucu yeteneğimi arttırmam gerekmediğinden para tasarrufu yapmam gerekir.

Sonuçta, sizin için işlem yapan 100+ masaüstü / tablet / cep telefonu kolektif gücü ile, sunucunuzdan çok daha fazla bir güç, bir veri merkezinde oturmaktan daha fazla bir yerdedir ve her ay işletmeye devam etmek için işletme paranızı ödeyebilir. Potansiyel olarak, o zaman tüm sunucunuz yapacağınız veriyi veri tabanından almak, içeriğe hizmet vermek ve veri tabanına geri koymadan önce bir miktar ön / son işlem ve verilerin doğrulanması olacaktır. Açıkçası, istemci tarafı kodunu, web tarayıcısının UI'sini engelleyebilecek / dondurabilecek CPU'yu yoğunlaştırmazsınız, AJAX isteğini sunucuya gönderebilir, verileri alabilir ve ardından verileri zaman uyumsuz olarak istemci tarafında işleyebilir ve web'den çıkabilirsiniz. -Browser UI tamamen kullanılabilir.


2

Evet, kullanılabilir. Diğerleri çeşitli yaklaşımlardan bahsetti. İşte benim kendi yaklaşımım. Avantajı tamamen taşınabilir ve kendi kendine yeten olmasıdır, seçilen tüm kütüphaneler yalnızca ANSI C'ye bağlıdır. Ayarlama yalnızca Linux Çekirdeği ve bir C derleyicisi gerektirir (ve Busybox, bash, vb. Gibi belirgin şeyler) (veya Windows ve bir derleyici), fazladan kütüphaneye gerek yok, çok fazla büyük kurulum gerektirmiyor.

Sonuç, hem web sunucusu hem de dinamik sayfa üreteci olan tek bir programdır (hem "apache" hem de "php" yi değiştirir), ayrıca sqlite üzerinden veri tabanı erişimine sahip olacaktır.

Kullanılan kütüphaneler:

  • Mongoose - Http sunucusu
  • Sqlite - SQL Veritabanı
  • MiniXML - Dinamik sayfa oluşturmayı kolaylaştırır. Javascript benzeri bir şeycreateElement

Bu cevabın geri kalanı Linux için eksiksiz bir kurulum rehberidir. Hem SQlite hem de MiniXML isteğe bağlıdır, ancak kılavuz tam kurulumu kapsar. Sqlite veya MiniXML'yi devre dışı bırakmakla ilgilenmiyorsanız, gerekli olmayan parçaları yorumlamak size kalmıştır.

1. 3 kütüphaneyi indirin

2. Klasörünüzü hazırlayın

  • Boş bir klasör oluşturun (Ana klasör diyoruz)
  • Aşağıdaki dosyaları içine yerleştirin:
    • Sqlite tar.gz'den: sqlite3.c , sqlite3.h
    • Mongoose zip’inden: mongoose.c , mongoose.h
    • Mxml tar.gz'den: mxml.h

3. mxml'yi derleyin

Mxml.c'nin eksik olduğunu fark etmiş olabilirsiniz, bunun nedeni statik bir mxml kütüphanesi oluşturmamız gerektiğidir. Mxml tar.gz dosyasının indirildiği klasöre gidin ve gerçekleştirin:

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.

Derleme tamamlandığında, birçok dosya oluşturulacak, ilgilendiğimiz tek dosya libmxml.abu dosyayı ana klasöre kopyalamaktır.

3.1 Şüphe

Ana klasörde aşağıdakilerin olup olmadığını kontrol edin:

  • Gelincik için: mongoose.c, mongoose.h
  • Mxml için: libmxml.a, mxml.h
  • sqlite için: sqlite.c, sqlite.h

4. ana.c

Haydi asıl programı oluşturalım main.c, ana klasörde bir dosya oluşturalım , işte başlayabilmen için bir iskelet.

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

Sonunda derleme!

Derleyelim. cdAna klasörünüze ekleyin ve bunları yürütün:

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 . 

Şimdi server.out ile yürütün /server.outve şuraya gidin:localhost:8080/hello

Tamam :)



@ Hey: Bu Mongoose alternatifini gösterdiğiniz için teşekkür ederim, ben hep topluluk odaklı projeleri tercih ederim. Muhtemelen iyice test ettikten sonra Mongoose'u Civetweb ile değiştireceğim.
Merhaba Dünya

0

Bazı gömülü sistemlerin (örneğin yönlendiriciler, yazıcılar, ...) bazı C ++ yönlendirmeli web sunucularına sahip olduğunu tahmin ediyorum.

Özellikle, bazı C veya C ++ programlarına bazı web yetenekleri eklemek veya bazı web arayüzlerine sahip hafif bir sunucu geliştirmek için libonion gibi bazı HTTP sunucu kütüphanelerini kullanabilirsiniz .

Bazı insanlar Ocsigen kullanarak Web sunucularını veya HTTP arayüzlerini Ocaml'da kodlar . Her web şeyi PHP değildir. Ve FastCGI ile uygulamanızın içinde / içinde bazı dinamik web işlemleri yapabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.