From c617b03e3c0c998de14c1125ee2feb68d276df71 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Thu, 16 Aug 2012 16:11:19 -0400 Subject: [PATCH] Erlang implementation --- chat.erl | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 chat.erl diff --git a/chat.erl b/chat.erl new file mode 100644 index 0000000..a5a80ca --- /dev/null +++ b/chat.erl @@ -0,0 +1,57 @@ +-module(chat). + +-export([start/0]). + +start() -> + IndexPid = spawn(fun () -> index([]) end), + {ok, LSock} = gen_tcp:listen(5999, [{active, true}, {packet, line}, {reuseaddr, true}]), + accept_loop(LSock, IndexPid). + +accept_loop(LSock, IndexPid) -> + case gen_tcp:accept(LSock) of + {ok, Sock} -> + gen_tcp:controlling_process(Sock, spawn(fun () -> connection(Sock, IndexPid) end)), + accept_loop(LSock, IndexPid) + end. + +index(Connected) -> + receive + {arrive, Pid} -> + [begin + P ! {utterance, {arrive, Pid}}, + Pid ! {utterance, {arrive, P}} + end || P <- Connected], + monitor(process, Pid), + index([Pid | Connected]); + {'DOWN', _, process, Pid, _} -> + NewConnected = Connected -- [Pid], + [P ! {utterance, {depart, Pid}} || P <- NewConnected], + index(NewConnected); + M = {_Pid, says, _Thing} -> + [P ! {utterance, M} || P <- Connected], + index(Connected); + Other -> + error_logger:error_report({index, unhandled, Other}) + end. + +say(Sock, V) -> + gen_tcp:send(Sock, io_lib:format("~p~n", [V])). + +connection(Sock, IndexPid) -> + IndexPid ! {arrive, self()}, + say(Sock, {you_are, self()}), + connection_mainloop(Sock, IndexPid). + +connection_mainloop(Sock, IndexPid) -> + receive + {utterance, V} -> + say(Sock, V), + connection_mainloop(Sock, IndexPid); + {tcp, _, Line} -> + IndexPid ! {self(), says, Line}, + connection_mainloop(Sock, IndexPid); + {tcp_closed, _} -> + ok; + Other -> + error_logger:error_report({connection, unhandled, Other}) + end.