This week I had to write a little tool that would collect input on different channels, via socket / netcat, via a http server, .... Calls for a parralel Design -- Maybe a good place to write something real in Erlang. While erlang itself was really nice to write -- I do like Prolog as well as the bunch of functional languages -- doing networking in erlang seems a bit special, the interfaces just aren't thin wrappers around the libc stuff. Getting a Socket Text interface What sounds like a easy challenge to accomplish was actually harder than expected. All I found was some way to pass binaries representing erlang code over a socket and evaluating it remotle. While it's nice that such things are as easy to do as they are it doesn't help me with my task of moving simple strings.
So the socket is now up and receives text as wanted. However, as we are already runnign a parralel program it would be nice to be hable to handle multiple socket connections in parralel right? For that we just need to add a
start() -> ok, Listen = gen_tcp:listen(51622, [binary, packet, 0 , reuseaddr, true , active, true ]), spawn(fun () -> accept_loop(Listen) end). accept_loop(Listen) -> ok, Socket = gen_tcp:accept(Listen), accept_loop(Listen), handle(Socket) handle(Socket) -> receive tcp, Socket, Bin -> io:format("~p~n", binary_to_list(Bin)); tcp_closed, Socket -> Buffer end.
spawn()at the right place. The right place is not the
accept_loop(Listen)because the process that called
acceptwill receive all the tcp messages. This last part was quite obvious after finding the documentation of the
active, _properties for the socket.
alwayshere means that you'll receive all data from the socket as erlang Messages,
oncedelivers one package and waits until it is activated again and
falserequires calling a method -- this would have been possible as well when forking
handle(Socket). The web server Ok we also want a webserver. We do not want to run some webapplication inside appache or so, just do some post/get and simple pages. Erlang here provides a built-in
mod_esithat calls some function depending on the URL used. It doesn't do anything fancy like templating or DB backends or stuff, just taking strings and building the http answers. Unfortunately there are no examples around and basically noone seems to be using this combination (apart from some hacks like mine probably). So as I needed to get some additional information into the handler function (a
Pidto connect to some service), I, as a novice, just couldn't find a way. Asking on IRC the solution was rather simple: Just using erlang's process registry. For more complex stuf
gprocmight prove usefull here. Result I guess I've got a huge step farther in programming erlang now. The manpages are easily found by your search engine -- for python I have to either walk through the (well structured) online documentation or search for the right link in the search results, for erlang they're typically first. Also Joe Armstrong's Books as proven usefull. The most dificult part probably is getting around all the nice extras you can do (transfering functions over sockets et al) and find out how to do the thing you need.