Thursday, January 28, 2010

Helloworld with Mochiweb

ใน erlang ถ้าคิดว่าจะใช้อะไรเป็น web server ดี ก็ต้องคิดถึง Yaws ก่อนเพื่อน
แต่ในระยะหลังเริ่มได้ยิน mochiweb และเห็นมี project ใหม่ๆที่นิยมใช้มากขึ้นเรื่อยๆ ก็เลยได้ฤกษ์ทำการทดสอบแบบง่ายๆ โดยจะ implement simple helloworld

เริ่มด้วยการ checkout source code ของ mochiweb ก่อน

svn checkout http://mochiweb.googlecode.com/svn/trunk/ mochiweb
cd mochiweb

จากนั้นก็สั่ง make เพื่อ compile code (แน่นอนว่าต้องติดตั้ง erlang รอไว้ก่อนแล้ว)

เริ่มต้นสร้างโปรเจค โดยสั่ง

escript /PATH_TO/mochiweb/scripts/new_mochiweb.erl helloworld

จะได้ directory หน้าตาประมาณนี้

./helloworld/
./helloworld/support/
run_tests.escript
include.mk
start.sh
start-dev.sh
./helloworld/src/
skel_web.erl
skel_sup.erl
skel_deps.erl
skel_app.erl
skel.hrl
skel.erl
skel.app
Makefile
./helloworld/priv/
./helloworld/priv/www/
index.html
Makefile
./helloworld/include/
./helloworld/doc/
./helloworld/deps/

file ที่เป็นหัวใจหลักก็คือ helloword_web.erl ทำหน้าที่เป็น process ที่ handle incoming request
ให้แก้ไข function loop ดังนี้
loop(Req, DocRoot) ->
"/" ++ Path = Req:get(path),
case Req:get(method) of
Method when Method =:= 'GET'; Method =:= 'HEAD' ->
case Path of
"helloworld" ->
Req:ok({"text/html", "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head><title >Welcome to mochiweb</title></head>
<body>
<h1>Helloworld</h1>
</body>
</html>"
});
_ ->
Req:serve_file(Path, DocRoot)
end;
'POST' ->
case Path of
_ ->
Req:not_found()
end;
_ ->
Req:respond({501, [], []})
end.


สั่ง run server โดยใช้คำสั่ง start-dev.sh
แล้วเรียก http://localhost:8000/helloworld

ถ้าเห็น crash report แบบนี้ อย่าตกใจ

=CRASH REPORT==== 28-Jan-2010::09:31:23 ===
crasher:
initial call: mochiweb_socket_server:acceptor_loop/1
pid: <0.57.0>
registered_name: []
exception error: bad argument
in function erlang:universaltime_to_localtime/1
called as erlang:universaltime_to_localtime({{1969,12,31},
{23,59,59}})

มันเป็น bug ใช้วิธี export TZ=GMT-7 แก้ปัญหาไปพลางๆก่อน

ทดลองแก้ไข code แล้วสั่ง refresh browser จะเห็นว่ามันไม่ reload ให้
ไม่ต้องเศร้าใจ ให้เปิด command prompt สั่ง make , ใน development mode, mochiweb จะตรวจดูว่า binary code เปลี่ยนหรือไม่ ถ้าเปลี่ยนมันจะ reload ให้เอง

ลองเปลี่ยน code ให้ รับ url /helloworld/ANYNAME แล้วแสดง message Hello ANYNAME ดูบ้าง
                case Path of
"helloworld/" ++ ID ->
Msg = io_lib:format("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head><title >Welcome to mochiweb</title></head>
<body>
Hello ~s
</body>
</html>"
, [ID]),
Req:ok({"text/html", Msg});

Related link from Roti

3 comments:

Anonymous said...

คราวที่แล้วที่ผมลอง แล้วไม่ได้ ติดบัก ตัวนี้แหละครับ
เดี๋ยวต้องลองทำตามดูอีกทีครับ

Sirn said...

บั๊กนี้ตอนแรกเห็นคุยกันใน mailing list ว่าจะแพชใน R13B04 แต่ไปๆ มาๆ กลับไม่ได้ merge คิดว่าใน R13B05 น่าจะแก้ครับ

(แต่แพชมัน submit ไปสองปีแล้ว...)

PPhetra said...

patch ลูกเมียน้อย