92 lines
1.9 KiB
Elixir
92 lines
1.9 KiB
Elixir
module Chat
|
|
module Client
|
|
module Room
|
|
def __bound__(room)
|
|
@('room: room)
|
|
end
|
|
|
|
def join
|
|
send 'join
|
|
end
|
|
|
|
def say(message)
|
|
send { 'say, message }
|
|
end
|
|
|
|
def leave
|
|
send 'leave
|
|
end
|
|
|
|
def flush
|
|
room = @room
|
|
receive { ~room, { 'message, message } }
|
|
IO.puts message
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def send(message)
|
|
room = @room
|
|
|
|
room <- { Process.current, message }
|
|
|
|
receive { ~room, response }
|
|
response
|
|
after 1000
|
|
IO.puts "Connection to room timed out!"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
module Server
|
|
module Room
|
|
def __bound__(clients)
|
|
@('clients: clients)
|
|
end
|
|
|
|
def loop
|
|
receive
|
|
match { pid, 'join }
|
|
notify_all Process.current, "Some user joined"
|
|
pid <- { Process.current, 'ok }
|
|
self.set_ivar('clients, [pid|@clients]).loop
|
|
match { pid, { 'say, message } }
|
|
notify_all(pid, message)
|
|
pid <- { Process.current, 'ok }
|
|
loop
|
|
match { pid, 'leave }
|
|
pid <- { Process.current, 'ok }
|
|
room = self.set_ivar 'clients, @clients.delete(pid)
|
|
room.notify_all Process.current, "Some user left"
|
|
room.loop
|
|
end
|
|
end
|
|
|
|
def notify_all(sender, message)
|
|
@clients.each do (c)
|
|
if c != sender
|
|
c <- { Process.current, { 'message, message } }
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
client = Process.current
|
|
server = Process.spawn -> #Chat::Server::Room([client]).loop
|
|
|
|
room = #Chat::Client::Room(server)
|
|
|
|
% Spawn another process to simulate another client that will
|
|
% join the room, send a message and leave.
|
|
Process.spawn do
|
|
another_client = #Chat::Client::Room(server)
|
|
another_client.join
|
|
another_client.say "Hi!"
|
|
another_client.leave
|
|
end
|
|
|
|
3.times -> room.flush |