%% Author: amk, mmu %% Created: 02.01.2008 %% Description: Serverloser chat. Problemchen: %% Partner werden nur aus den PIDs entfernt, wenn sie sich ordnungsgemäß %% verabschieden. Ansonsten werden ihnen auf ewig alle Nachrichten zugeschickt %% -> funktioniert, aber nicht effizient. -module(chat). %% %% Include files %% -import(base). %% %% Exported Functions %% -export([start/1,start/3,reader/1]). %% %% API Functions %% start(Nick) -> spawn_link(chat,reader,[self()]), register(Nick,self()), chat(Nick,[self()]). %% Beispiel: chat:start(myNick,'nodename@1.2.3.4',partnerNick). start(Nick,Node,NodeNick) -> {NodeNick,Node}!{getlist,self()}, start(Nick). reader(P) -> Line = base:getLn("> "), P!{input,Line}, reader(P). %% %% Local Functions %% chat(Nick,PIDs) -> receive {input,"/quit"} -> lists:foreach(fun(P) -> P!{quit,Nick,self()} end, PIDs), exit(-1); {input,Line} -> Hash = hash(PIDs), lists:foreach(fun(P) -> P!{message,Nick,Line,Hash,self()} end, PIDs), chat(Nick,PIDs); {getlist,PID} -> PID!{list,PIDs}, chat(Nick,PIDs); {list,ReceivedPIDs} -> NewPIDs = lists:subtract(ReceivedPIDs, PIDs), lists:foreach(fun(P) -> P!{join,Nick,self()} end,NewPIDs), chat(Nick,lists:append(NewPIDs,PIDs)); {join,SendNick,PID} -> case lists:any(fun(P) -> P == PID end, PIDs) of false -> base:print(SendNick), base:printLn(" has joined the Chat."), NewPIDs = [PID|PIDs], chat(Nick,NewPIDs); true -> chat(Nick,PIDs) end; {quit,SendNick,PID} -> base:print(SendNick), base:printLn(" has left the Chat."), chat(Nick,lists:delete(PID,PIDs)); {message,SendNick,Line,Hash,PID} -> base:print(SendNick),base:print(" "), base:printLn(Line), case hash(PIDs) of Hash -> 42; _ -> PID!{getlist,self()}, PID!{list,PIDs} end, chat(Nick,PIDs) end. hash(Val) -> erlang:phash2(lists:sort(Val), 4294967296).