2010-02-05 3 views
29

Используя установку по умолчанию Erlang, каков минимальный код, необходимый для создания веб-сервера «Hello world»?Как написать простой веб-сервер в Erlang?

+0

Как это отличается от http://stackoverflow.com/questions/2084639/sinatra-style-web-framework-for-erlang? – Zed

+1

@ Zed, Zubair просит минимальный сервер «привет мир» - у него есть одна «страница», потому что она минимальна. Вопрос, который вы связали, задает вопрос о том, как создать функциональное веб-приложение (одностраничное, но реагирует на различные запросы по-разному). Я предполагаю, что последний будет ajax-y. – apollodude217

ответ

49

Принимая «производить» буквально, здесь довольно маленький. Он даже не читает запрос (но делает вилку по каждому запросу, поэтому это не так минимально возможно).

-module(hello). 
-export([start/1]). 

start(Port) -> 
    spawn(fun() -> {ok, Sock} = gen_tcp:listen(Port, [{active, false}]), 
        loop(Sock) end). 

loop(Sock) -> 
    {ok, Conn} = gen_tcp:accept(Sock), 
    Handler = spawn(fun() -> handle(Conn) end), 
    gen_tcp:controlling_process(Conn, Handler), 
    loop(Sock). 

handle(Conn) -> 
    gen_tcp:send(Conn, response("Hello World")), 
    gen_tcp:close(Conn). 

response(Str) -> 
    B = iolist_to_binary(Str), 
    iolist_to_binary(
     io_lib:fwrite(
     "HTTP/1.0 200 OK\nContent-Type: text/html\nContent-Length: ~p\n\n~s", 
     [size(B), B])). 
+3

См. '{Пакет, http}' '' '' '' gen_tcp: listen' для декодирования HTTP-заголовков. – Pindatjuh

+1

Я смотрел этот код, и хотя он выглядит чистым, я нашел проблему. При тестировании с помощью Apache Bench я получаю сообщение apr_socket_recv: Connection reset by peer (104) '. он отлично работает при доступе в браузере или с помощью завитки. У вас есть идеи, почему это так? –

+1

@MartinKristiansen Удалить строку 'gen_tcp: close (Conn) .' –

8

Вы действительно хотите написать веб-сервер в Erlang или хотите веб-сервер Erlang, чтобы вы могли создавать динамический веб-контент с помощью Erlang?

Если последний, попробуйте YAWS. Если первый, посмотрите на YAWS source code для вдохновения

+2

Я хочу сделать динамический контент, но просто хочу знать минимальный минимум, необходимый для веб-сервера. Я посмотрел исходный код Yaws, и мое первое впечатление заключалось в том, что требуется много кода. – Zubair

12

Для веб-сервера, использующего только встроенные библиотеки, обращайтесь к inets http_server. Если вам нужна дополнительная мощность, но с простотой, вы должны проверить библиотеку mochiweb. Вы можете использовать Google для загрузки кода примера.

+1

Это здорово, поэтому с помощью INets я могу написать веб-сервер с одним модулем? – Zubair

5

Для очень простой в использовании веб-сервера для создания успокоительные приложений или такой проверить поведение gen_webserver: http://github.com/martinjlogan/gen_web_server.

1

Только одно исправление для ответа Феликса, и оно рассматривает проблемы, которые видит Мартин. Перед закрытием сокета должны быть получены все данные, отправляемые от клиента (с использованием, например, do_recv от gen_tcp description).

В противном случае существует условие гонки для браузера/прокси, отправляющего HTTP-запрос достаточно быстро, чтобы отправить HTTP-запрос до закрытия сокета.

2

Другой способ, аналогичный приведенному выше примеру gen_tcp, но с меньшим количеством кода и уже предлагаемый в качестве предложения, использует inets library.

%%% 
%%% A simple "Hello, world" server in the Erlang. 
%%% 

-module(hello_erlang). 
-export([ 
    main/1, 
    run_server/0, 
    start/0 
]). 

main(_) -> 
    start(), 
    receive 
    stop -> ok 
    end. 

run_server() -> 
    ok = inets:start(), 
    {ok, _} = inets:start(httpd, [ 
    {port, 0}, 
    {server_name, "hello_erlang"}, 
    {server_root, "/tmp"}, 
    {document_root, "/tmp"}, 
    {bind_address, "localhost"} 
    ]). 

start() -> run_server().              

Имейте в виду, это подвергает свой /tmp каталог.

Для запуска, просто:

$ escript ./hello_erlang.erl 
Смежные вопросы