使用默认的Erlang安装生成“Hello world”生成Web服务器所需的最小代码是什么?
答案 0 :(得分:49)
从字面上看“产品”,这是一个非常小的一个。它甚至没有读取请求(但是在每个请求上都是fork,所以它不是那么简单)。
-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])).
答案 1 :(得分:11)
对于仅使用内置库的Web服务器,请查看inets http_server。 当需要更多功能但仍然简单时,您应该查看mochiweb库。您可以谷歌搜索大量示例代码。
答案 2 :(得分:7)
您真的想在Erlang中编写Web服务器,还是想要Erlang Web服务器以便使用Erlang创建动态Web内容?
如果是后者,请尝试YAWS。如果是前者,请查看YAWS source code获取灵感
答案 3 :(得分:4)
对于一个非常容易使用的网络服务器来构建restful应用程序或类似检查gen_webserver行为:http://github.com/martinjlogan/gen_web_server。
答案 4 :(得分: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
答案 5 :(得分:1)
只有一个修复Felix的答案,它解决了马丁所看到的问题。在关闭套接字之前,应该接收从客户端发送的所有数据(例如使用来自gen_tcp description的do_recv
)。
否则,浏览器/代理的竞争条件是发送HTTP请求足够快,以便在套接字关闭之前发送http请求。