2010-02-05 32 views
29

Sử dụng cài đặt Erlang mặc định, mã tối thiểu cần thiết để tạo ra một máy chủ web "Hello world" là gì?Làm thế nào để viết một máy chủ web đơn giản trong Erlang?

+0

Làm thế nào này khác gì so http://stackoverflow.com/questions/2084639/sinatra-style-web-framework-for-erlang? – Zed

+1

@Zed, Zubair đang yêu cầu một máy chủ "hello world" tối thiểu - nó có một "trang" đơn vì nó rất nhỏ. Câu hỏi bạn đã liên kết để hỏi làm thế nào để tạo một ứng dụng Web chức năng (một trang, nhưng trả lời cho nhiều yêu cầu theo nhiều cách khác nhau). Tôi cho rằng cái sau sẽ là ajax-y. – apollodude217

Trả lời

49

Lấy "sản xuất" theo nghĩa đen, đây là một sản phẩm khá nhỏ. Nó thậm chí không đọc các yêu cầu (nhưng không ngã ba trên mọi yêu cầu, do đó, nó không phải là tối thiểu có thể).

-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

Xem '{packet, http}' cho 'Tùy chọn' của' gen_tcp: listen' để giải mã tiêu đề HTTP. – Pindatjuh

+1

Tôi đã xem mã này, và mặc dù nó trông sạch sẽ, tôi đã tìm thấy một vấn đề. Khi thử nghiệm nó với Apache Bench, tôi nhận được một 'apr_socket_recv: Connection reset by peer (104)'. nó hoạt động tốt khi truy cập trong trình duyệt hoặc sử dụng curl. Bạn có bất kỳ ý tưởng tại sao điều này? –

+1

@MartinKristiansen Xóa dòng 'gen_tcp: close (Conn). ' –

8

Bạn có thực sự muốn viết một máy chủ web trong Erlang hay bạn muốn một máy chủ web Erlang để bạn có thể tạo nội dung web động bằng Erlang?

Nếu sau, hãy thử YAWS. Nếu trước đây, hãy xem YAWS source code để biết cảm hứng

+2

Tôi muốn tạo nội dung động nhưng chỉ muốn biết mức tối thiểu cần thiết cho máy chủ web. Tôi nhìn vào mã nguồn Yaws và ấn tượng đầu tiên của tôi là rất nhiều mã là cần thiết. – Zubair

12

Đối với máy chủ web chỉ sử dụng thư viện được tích hợp, hãy kiểm tra inets http_server. Khi cần thêm chút sức mạnh nhưng vẫn đơn giản, bạn nên kiểm tra thư viện mochiweb. Bạn có thể google cho tải mã ví dụ.

+1

Thats tuyệt vời, vì vậy sử dụng INET tôi có thể viết một máy chủ web mô-đun không? – Zubair

1

Chỉ cần một sửa chữa cho câu trả lời của Felix và nó giải quyết các vấn đề mà Martin đang thấy. Trước khi đóng ổ cắm, tất cả dữ liệu được gửi từ máy khách phải được nhận (sử dụng ví dụ do_recv từ gen_tcp description).

Nếu không có điều kiện chủng tộc cho trình duyệt/proxy gửi yêu cầu HTTP đủ nhanh để gửi yêu cầu http trước khi đóng socket.

2

Một cách khác, tương tự như ví dụ gen_tcp ở trên nhưng có ít mã hơn và đã được cung cấp dưới dạng đề xuất, đang sử dụng 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().              

Lưu ý, điều này sẽ hiển thị thư mục /tmp của bạn.

Để chạy, chỉ cần:

$ escript ./hello_erlang.erl 
Các vấn đề liên quan