it-swarm.asia

C ++, sunucu tarafı web geliştirme dili olarak kullanılabilir mi?

Sunucu tarafında "komut dosyası dili" olarak C++ kullanarak web geliştirme almak istiyorum. Sunucu altyapım * nix tabanlıdır, bu nedenle Azure'da C++ ile web geliştirme yapmak geçerli değildir ve C++/CLI ASP.NET de geçerli değildir.

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

34
Scott Davies

Kesinlikle.

Bunları geliştirmek için Wt , cppcms , CSP ve diğerleri de dahil olmak üzere birkaç çerçeve vardır. FastCGI'ın ana hat uygulaması C'dir ve C++ dahil olmak üzere birkaç dil öğesini doğrudan destekler.

Dizeleri ayrıştırabilen herhangi bir programlama dili CGI veya sunucu uygulamasında kullanılabilir. C kitaplıklarıyla bağlantı kurabilen herhangi bir dil, ISAPI veya Apache uyumlu sunucular için modüller geliştirmek için de kullanılabilir.

C++ 'da özellikle kolay değildir ve iyi şablonlama motorları çok azdır, ancak yapılabilir.

Tabii ki, 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 bazı bölümleri için C++ kullanır. Bununla birlikte, Google'ın hız açısından kritik sistemler için yalnızca C++ kullandığını ve Amazon.com'un nispeten kısa bir süre önce LISP'den (üst düzey personelinin bazılarını kızdırdığı) uzaklaştığını anlayın.

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

56
greyfade

Neden olmasın?

OkCupid tanışma sitesi C++ ile oluşturulur. Muhtemelen başka örnekler de vardır.

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

18
Vitor Py

Web uygulamanızı C++ ile yazmayı planlıyorsanız, daha sonra CGI olarak arayüz haline getirmek toplam atık olacaktır.

Benim önerim ASIO (Asenkron I/O) kullanarak senkronize olmayan bir yapı oluşturmak olacaktır. Bununla birlikte hızlı web hizmeti oluşturabilirsiniz (en iyi efektler için ters proxy olarak nginx ve statik sunucu ile birleştirin); Bunu Wt gibi şablon kütüphanesiyle birleştirdiğinizde, tek bir sunucudan saniyede on binlerce istek sunmaya hazırsınız.

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

11
vartec

Kısa cevap, HERHANGİ bir giriş yazmak, yorumlanabilir çıktı yazmak ve web sunucusu tarafından yürütülebilir olması koşuluyla bir web sayfası yazmak için kullanılabilir.

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

  1. Sunucu tarafından sunulan tüm girişleri 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, ikisi arasında bir yorumlama katmanı olarak işlev gören c/c ++ kodu etrafında bir sarmalayıcı olarak inşa edilebilme yeteneğine sahiptir (ve bu, C olarak derlenmiş düz Perl modülleri dahil değildir).

9
Avatar_Squadron

başlangıçta oldukça yaygındı - 1990'ların sonunda üzerinde çalıştığım ilk web siteleri C++ ile yazılmış ISAPI uzantılarıydı ve oldukça iyi çalıştılar.

7
Steven A. Lowe

Görünüşe göre Microsoft da yapabileceğini düşünüyor. C++ kullanarak Azure için yeni bir takım olan Casablanca 'a göz atın.

Kazablanka, bulut bilişimin temsil ettiği yazılım mimarisindeki radikal değişimden yararlanmak isteyen C++ geliştiricilerini en iyi nasıl destekleyeceğini keşfetmeye başlamak için bir projedir.

Kazablanka ile şunları elde edebilirsiniz:

  • HTTP, JSON ve URI'lara eşzamansız C++ bağlamaları sağlayarak REST hizmetlerine Windows Vista, Windows 7 ve Windows 8 Tüketici Önizlemesi'nde yerel koddan erişme desteği
  • Windows 8 Metro stili uygulamanızda C++ HTTP istemci tarafı kodu yazmanıza yardımcı olacak bir Visual Studio uzantısı SDK'sı
  • Yerel kod yazma desteği REST
  • Birinci sınıf Hizmet olarak Platform (PaaS) özelliği olarak yerel istemcilerden Azure blob ve kuyruk depolama alanına erişmek için uygun kitaplıklar
  • C++ 11 özelliklerine dayalı eşzamansız işlemler oluşturmak için tutarlı ve güçlü bir model
  • Erlang aktör tabanlı programlama modelinin C++ uygulaması
  • Bir dizi örnek ve dokümantasyon
5
gbjbaanb

PHP için kendi C/C++ uzantılarınızı yazabilirsiniz ve bu şekilde iyi performans avantajları elde edebilirsiniz.Web uygulamamın gerçekten CPU yoğun bir parçası olsaydı muhtemelen işlemeyi uzantıya yükleyen ve ardından sonucu tekrar PHP ve ardından PHP tarayıcıya çıktılar) döndüren küçük bir C++ kitaplığı oluşturun.

İnsanların sık sık düşünmediği diğer şey, belirli CPU işlemlerini istemci tarafına boşaltmaktır. JavaScript/jQuery. Bir web sunucum varsa, belirli bir işlev (belki bazı veri işleme) için CPU yoğun işlem yapmak için 3Ghz CPU'ya ihtiyacım olabilir. Şirketim her ay bu sunucu için çalışmasını sağlamak için para ödüyor. Bu CPU yoğun görevini aynı anda çalıştıran 100 eşzamanlı kullanıcı için işlemleri ölçeklendirmek istersem, belki de birden fazla CPU ve sunucuya ihtiyacım var, bu da işimin maliyetini arttırıyor. Bu CPU yoğun görevini istemci tarafına yüklersem, web sitesini ziyaret eden her kullanıcı veriler üzerinde kendi işlemlerini yapabilir ve sunucu kapasitemi artırmak zorunda değilim, bu yüzden bana para kazandırır.

Sonuçta 100 + masaüstü/tablet/cep telefonlarının kolektif gücü ile sizin için işlem yapıyor, sunucunuzun çalıştığı her yerde iş paranıza mal olan bir veri merkezinde oturan sunucunuzdan çok daha fazla güç. Potansiyel olarak tüm sunucunuzun yapacağı veritabanından veri almak, içerik sunmak ve veritabanına geri saklamadan önce verilerin bir miktar ön/son işlem ve doğrulaması olacaktır. Açıkçası, istemci tarafı kodunu web tarayıcı arayüzünü engelleyebilecek/dondurabilecek kadar CPU yoğunlaştırmayacaksınız, sunucuya bir AJAX isteği gönderebilir, verileri alabilir ve daha sonra web tarayıcı kullanıcı arayüzünü tamamen kullanılabilir durumda bırakarak senkronize olmayan istemci tarafı verileri.

2
zuallauz

Evet, kullanılabilir. Diğerleri çeşitli yaklaşımlardan bahsetti. İşte benim kendi yaklaşımım. Avantajı, tamamen taşınabilir ve bağımsız olması, tüm seçilen kitaplıkların yalnızca ANSI C'ye bağlı olmasıdır. Kurulumu için sadece Linux Çekirdeği ve bir C derleyicisi gerekir (Ve Busybox, bash, vb. Gibi bariz şeyler) (veya Windows ve bir derleyici), ekstra kütüphaneye gerek yok, süslü büyük kurulumlar yok.

Sonuç, hem bir web sunucusu hem de dinamik bir sayfa oluşturucu (hem "Apache" hem de "php" yerine geçer) olan tek bir programdır, ayrıca sqlite üzerinden veritabanı 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'in createElement benzeri

Bu cevabın geri kalanı Linux için eksiksiz bir kurulum kılavuzudur. Hem SQlite hem de MiniXML isteğe bağlıdır, ancak kılavuz tam kurulumu kapsar. Sqlite veya MiniXML'yi devre dışı bırakmak istiyorsanı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 (Biz buna ana klasör deriz)
  • Aşağıdaki dosyaları içine koyun:
    • Sqlite tar.gz'den: sqlite3.c , sqlite3.h
    • Mongoose Zip'ten: mongoose.c , mongoose.h
    • Mxml tar.gz'den: mxml.h

3. Mxml'i 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 bittikten sonra birçok dosya oluşturulacaktır, ilgilendiğimiz tek dosya libmxml.a 'Dır, bu dosyayı ana klasöre kopyalayın.

3.1 Şüphe

Ana klasörde aşağıdakilerin bulunduğundan emin olun:

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

4. main.c

Gerçek programı oluşturalım, ana klasörde bir main.c Dosyası oluşturalım, işte başlamanız 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. cd ana 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 İle server.out komutunu yürütün ve localhost:8080/hello Öğesine gidin

Tamamlandı :)

2
Hello World

Birkaç gömülü sistemin (örneğin, yönlendiriciler, yazıcılar, ...) bazı C++ tabanlı web sunucusu 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ı kişiler Web sunucularını veya HTTP arayüzlerini Ocaml'de Ocsigen kullanarak kodlar. Her web şey PHP değildir. Ve FastCGI ile uygulamanızda/uygulamanızda dinamik web işleme yapabilirsiniz.