Чи можна C ++ використовувати як серверну мову веб-розробки? [зачинено]


34

Я б хотів увійти в веб-розробку, використовуючи C ++ як "мову сценаріїв" на стороні сервера. Моя серверна інфраструктура заснована на * nix, тому розробка веб-розробок у C ++ на Azure не застосовується, а C ++ / CLI ASP.NET також не застосовується.

Чи можна розробити веб-розробки за допомогою застарілих програм CGI за допомогою C ++?


33
Звичайно, це можливо , питання є; це практично ?
Ред С.

Дивіться це запитання на сайті stackoverflow.com.
кевін клайн

24
Ви можете використовувати збірку як мову на стороні сервера, якби ви були настільки схильні.
Канал72

8
Або навіть Brainf * ск , якщо ,будуть .перенаправлені на сокет.
dan04

4
Це повертає жахливі спогади першого веб-проекту, в якому я брав участь. Шлюзи CGI до коду C. Я все ще здригаюся, коли думаю про це! :-)
Брайан Ноблеуч

Відповіді:


56

Абсолютно.

Існує навіть кілька рамок для їх розробки, включаючи Wt , cppcms , CSP та інші. Основна реалізація FastCGI знаходиться на C та безпосередньо підтримує декілька мов , включаючи C ++.

Будь-яка мова програмування, яка може проаналізувати рядки, може використовуватися в CGI або сервлеті. Будь-яка мова, яка може реалізувати зв'язки з бібліотеками С, також може використовуватися для розробки модулів для серверів, сумісних з ISAPI або Apache.

У C ++ це не особливо просто, і хороших двигунів для шаблонів небагато та далеко між, але це можна зробити.

Звичайно, питання про те, чи це гарна ідея, зовсім інше. :)

Зверніть увагу: основні веб-сайти, такі як Amazon.com, eBay і Google, використовують C ++ для частини своєї інфраструктури. Зрозумійте, однак, що Google використовує лише C ++ для систем, що мають важливу швидкість, а Amazon.com лише порівняно недавно відключився від Lisp (що розлютило деяких їх старших працівників :).

Раніше Facebook збирав PHP на C ++, але їх компілятор HipHop (написаний частково на C ++) з тих пір переосмислювався як віртуальна машина байт-коду.


2
+1 Для посилань на різні рамки. Слід додати, що для (дуже) великих веб-додатків зазвичай працює c ++ (та іншими мовами): amazon.com, google.com, зараз facebook.com через hiphop тощо.
Klaim

7
@Klaim: Це звичайно, але це аж ніяк не правило. Історія архітектури Amazon була заснована на Ліспі і лише нещодавно переписана на C ++. Архітектура Google включає Java, Python та інші майже так само часто, як C ++, і все це з різних причин. Facebook зараз використовує хіпхоп лише тому, що з'ясував, що PHP не змінюється. :)
greyfade

4
Я погоджуюся, але я мав на увазі, що вони все ще є відомими прикладами використання C ++ - щоб відповісти безпосередньо на оригінальну назву питання.
Клаїм

1
@johannes Проблема масштабування Facebook випливає з того, що їм доводиться підтримувати на порядок більше серверів, ніж це потрібно, зокрема через низьку продуктивність оптимізованого сценарію PHP. Лінійне масштабування просто недостатньо добре для такої великої інфраструктури. Але пам’ятайте, що підхід «нічого спільного» не є виключним для PHP. C і C ++ теж можуть це зробити.
greyfade

1
@amar Справа в тому, що повернення мало, за винятком 0,1% додатків, які потребують такої сильної продуктивності. Ви можете обслуговувати в 1/3 часу на більшості інших мов з хорошою підтримкою веб-стеків. Банки, веб-рекламодавці тощо надають масштабні масштаби, не вдаючись до C ++. Навіть Facebook. Twitter. Переповнення стека. Усі роблять це мовами вищого рівня. Тут залишитися, але вона знову не стане більшості. Напевно, коли-небудь.
Rig

18

Чому ні?

OkCupid сайт знайомств створений з C ++. Напевно, є й інші приклади.

Існує також натхненний Qt інструментарій для розробки веб-додатків із C ++ під назвою Wt .


11
"Чому ні "? Тому що набагато простіше використовувати мову, яка підтримує подібні речі.
Ред С.

5
@Ed S. Як я і Greyfade зазначали, існують рамки для розробки веб-додатків на C ++.
Vitor Py

2
Так, але знову ж таки, чи вони такі ж прості у використанні, як і більш часто використовувані рамки? Я чесно запитую, я не веб-розробник, і я ніколи їх не використовував, але щось говорить про те, що вони, ймовірно, не настільки зрілі або широко використовуються, як (наприклад) їх колеги рубін / пітон / PHP.
Ред С.

3
@EdS. Ні Рубі, ні Пітон не почалися з веб-фреймів. Насправді це пройшло десятиліття, щоб ті з'явилися. Ці рамки є лише наслідком достатньої кількості людей, які бажають використовувати мову X для проблеми Y. Те ж саме може статися і для C ++. Основні причини, чому цього не вдалося: C ++ не керується, займає віки для складання та загалом має більш високий бар'єр на вході.
back2dos

1
@ back2dos: Хто сказав, що будь-яка мова була розроблена з урахуванням Інтернету? Я точно не став. Я вжив термін «підтримка».
Ред С.

11

Якщо ви плануєте писати свою веб-програму на мові C ++, було б цілком сміттям потім інтерфейсувати її як CGI.

Моєю пропозицією було б побудувати його асинхронно за допомогою ASIO (Asynchronous I / O). Завдяки цьому ви можете створювати швидкі веб-сервіси (поєднуйте з nginx як сервер зворотного проксі-сервера та статики для найкращих ефектів); Поєднайте це з бібліотекою шаблонів, як Wt і ви готові обслуговувати десятки тисяч запитів в секунду з одного сервера.

Чи є це практичною альтернативою динамічній мовній веб-рамці - інше питання.


9

Коротка відповідь полягає в тому, що будь-що може бути використане для написання веб-сторінки за умови, що вона може читати вхід, писати інтерпретований вихід і виконується веб-сервером.

Технічно будь-яка мова може бути використана як сценарій CGI за умови:

  1. Інтерпретує всі входи та середовище, представлені сервером
  2. Виводи відомою мовою розмітки (як правило, html)
  3. Може управляти сервером

Є й інші способи. Perl має можливість будуватися як обгортка навколо коду c / c ++, виконуючи роль інтерпретаційного шару між цими двома (і це не включає модулі perl, які плоско складені як C).



5

Здається, Microsoft вважає, що це теж може. Перевірте Casablanca, який є новим набором інструментів для (як видається) Azure за допомогою C ++.

Casablanca - це проект, який повинен почати вивчати, як найкраще підтримати розробників C ++, які хочуть скористатися кардинальним зрушенням в архітектурі програмного забезпечення, яке представляє хмарні обчислення.

Ось що ви отримуєте з Касабланки:

  • Підтримка доступу до служб REST з нативного коду на Windows Vista, Windows 7 та Windows 8 Consumer Preview, надаючи асинхронні зв'язки C ++ до HTTP, JSON та URI
  • SDK з розширенням Visual Studio, який допоможе вам написати код клієнтської C ++ HTTP у вашому додатку в стилі метро Windows 8
  • Підтримка написання власного коду REST для Azure, включаючи інтеграцію Visual Studio
  • Зручні бібліотеки для доступу до зберігання блоків Azure та черг від рідних клієнтів як функція першокласного платформи як послуга (PaaS)
  • Послідовна і потужна модель складання асинхронних операцій на основі функцій C ++ 11
  • Впровадження C ++ моделі програмування на основі актора Ерланг
  • Набір зразків та документації

2

Для PHP ви можете написати власні розширення C / C ++ і таким чином отримати хороші переваги від продуктивності. Якби у мене була справді інтенсивна процесорна частина мого веб-додатку, я, ймовірно, зробив би невелику бібліотеку C ++, яка завантажила цю обробку в розширення, а потім повернула результат назад до PHP, а потім PHP виводить його у браузер.

Інша річ, яку люди часто не вважають, - це завантаження певної обробки процесора на сторону клієнта, наприклад, JavaScript / jQuery. Якщо у мене є веб-сервер, мені може знадобитися процесор 3 ГГц, щоб зробити інтенсивну обробку процесора для певної функції (можливо, деяку обробку даних). Моя компанія щомісяця платить гроші за цей сервер, щоб він не працював. Якщо я хочу збільшити масштаб операцій для 100 одночасних користувачів, які одночасно виконують це інтенсивне завдання процесора, то, можливо, мені потрібні декілька процесорів і серверів, що збільшує вартість мого бізнесу. Якщо я перевантажую це інтенсивне завдання процесора на сторону клієнта, то кожен користувач, який відвідує веб-сайт, може самостійно обробляти дані, і мені не потрібно збільшувати можливості сервера, тому економлячи гроші.

Зрештою, з сукупною потужністю 100+ настільних / планшетів / мобільних телефонів, які роблять для вас обробку, це набагато більше енергії, ніж ваш сервер, що сидить у центрі обробки даних, де щомісяця коштує ваших грошей бізнесу щомісяця, щоб продовжувати працювати. Потенційно тоді всі ваші сервери будуть займатися вилученням даних із бази даних, подачею вмісту та трохи попередньої та після обробки обробки та перевірки даних перед зберіганням назад у базі даних. Очевидно, що ви не зробили б код клієнтської сторони занадто інтенсивним, що може блокувати / заморозити користувальницький інтерфейс веб-браузера, ви можете запустити запит AJAX на сервер, отримати дані та обробити дані асинхронно на стороні клієнта, покинувши Інтернет -користувальницький інтерфейс користувача повністю придатний.


2

Так, це можна використовувати. Інші згадали про різні підходи. Ось мій власний підхід. Перевага полягає в тому, що вона повністю портативна та автономна, всі вибрані бібліотеки залежать лише від ANSI C. Для її налаштування потрібні лише ядро ​​Linux та компілятор C (і очевидні речі, такі як Busybox, bash тощо) (або Windows і компілятор), не потрібні зайві бібліотеки, не потрібні величезні установки.

Результат - це єдина програма, яка є і веб-сервером, і динамічним генератором сторінок (замінює і "apache", і "php"), вона також матиме доступ до бази даних через sqlite.

Використовувані бібліотеки:

  • Mongoose - Http сервер
  • Sqlite - база даних SQL
  • MiniXML - Полегшує генерацію динамічної сторінки. на зразок JavascriptcreateElement

Решта цієї відповіді - це повний посібник із налаштування для Linux. І SQlite, і MiniXML необов’язкові, але посібник охоплює повну інсталяцію. Ви можете коментувати не потрібні деталі, якщо ви зацікавлені в тому, щоб вимкнути sqlite або MiniXML.

1. Завантажте 3 бібліотеки

2. Підготуйте свою папку

  • Створіть порожню папку (ми її назвемо основною папкою)
  • Помістіть у нього такі файли:
    • З sqlite tar.gz: sqlite3.c , sqlite3.h
    • З монгузської блискавки: mongoose.c , mongoose.h
    • З mxml tar.gz: mxml.h

3. Складіть mxml

Можливо, ви помітили, що mxml.c відсутній, це тому, що нам потрібно створити статичну бібліотеку mxml. Перейдіть до папки, в яку було завантажено mxml tar.gz, і виконайте:

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.

Після завершення компіляції буде створено багато файлів, єдиний цікавий для нас libmxml.aфайл - скопіювати цей файл у головну папку.

3.1 Двічі

Переконайтеся, що основна папка має наступне:

  • Для мангуста: mongoose.c, mongoose.h
  • Для mxml: libmxml.a, mxml.h
  • для sqlite: sqlite.c, sqlite.h

4. main.c

Давайте створимо фактичну програму, створимо main.cфайл у головній папці, ось скелет для початку роботи.

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

Нарешті, складання!

Давайте складемо. cdдо вашої основної папки та виконайте такі:

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 . 

Тепер запустіть server.out /server.outі перейдіть доlocalhost:8080/hello

Готово :)



@Hey: Дякую, що вказав на цю альтернативу "Мангуст", я завжди віддаю перевагу проектам, керованим громадою. Я, мабуть, заміню мангусту на Civetweb у своїй відповіді після того, як я ретельно її перевіряю.
Hello World

0

Я думаю, що кілька вбудованих систем (наприклад, маршрутизатори, принтери, ...) мають якийсь веб-сервер, керований C ++.

Зокрема, ви можете використовувати якусь бібліотеку серверів HTTP, наприклад, libonion, щоб додати деякі веб-можливості до якоїсь програми C або C ++ або розробити легкий сервер з деяким веб-інтерфейсом.

Деякі люди кодують свій веб-сервер або свій HTTP-інтерфейс в Ocaml за допомогою Ocsigen . Не кожна веб-річ - PHP. І за допомогою FastCGI ви могли б зробити деяку динамічну обробку веб-сторінок у / до вашої програми.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.