如何在Erlang中编写简单的Web服务器?

时间:2010-02-05 11:48:55

标签: erlang

使用默认的Erlang安装生成“Hello world”生成Web服务器所需的最小代码是什么?

6 个答案:

答案 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 descriptiondo_recv)。

否则,浏览器/代理的竞争条件是发送HTTP请求足够快,以便在套接字关闭之前发送http请求。