Permalink
Browse files

Adiciona suporte a envio de mensagens offline.

  • Loading branch information...
1 parent 42dd1a6 commit 3237f47d8d6c5bbaa45ed7d478d1e17c66d36313 @carlosbrando committed Mar 28, 2011
Showing with 113 additions and 21 deletions.
  1. +2 −1 .gitignore
  2. +1 −0 README
  3. +8 −20 message_router.erl
  4. +77 −0 message_store.erl
  5. +25 −0 server_util.erl
View
@@ -1,2 +1,3 @@
*.beam
-*.tmproj
+*.tmproj
+Mnesia.*
View
@@ -0,0 +1 @@
+c(message_store). c(server_util). c(chat_client). c(message_router).
View
@@ -3,27 +3,12 @@
-compile(export_all).
start () ->
- global:trans({?SERVER, ?SERVER}, fun
- () ->
- case global:whereis_name(?SERVER) of
- undefined ->
- Pid = spawn(message_router, route_messages, [dict:new()]),
- global:register_name(?SERVER, Pid);
- _ ->
- ok
- end
- end).
+ server_util:start(?SERVER, {message_router, route_messages, [dict:new()]}),
+ message_store:start().
stop () ->
- global:trans({?SERVER, ?SERVER}, fun
- () ->
- case global:whereis_name(?SERVER) of
- undefined ->
- ok;
- _ ->
- global:send(?SERVER, shutdown)
- end
- end).
+ server_util:stop(?SERVER),
+ message_store:stop().
send_chat_message (ClientName, MessageBody) ->
global:send(?SERVER, {send_chat_msg, ClientName, MessageBody}).
@@ -41,10 +26,13 @@ route_messages (Clients) ->
{ok, ClientPid} ->
ClientPid ! {printmsg, MessageBody};
error ->
- io:format("Error! Unknown client: ~p~n", [ClientName])
+ message_store:save_message(ClientName, MessageBody),
+ io:format("Archived message for ~p~n", [ClientName])
end,
route_messages(Clients);
{register_nick, ClientName, ClientPid} ->
+ Messages = message_store:get_messages(ClientName),
+ lists:foreach(fun(Msg) -> ClientPid ! {printmsg, Msg} end, Messages),
route_messages(dict:store(ClientName, ClientPid, Clients));
{unregister_nick, ClientName} ->
case dict:find(ClientName, Clients) of
View
@@ -0,0 +1,77 @@
+-module (message_store).
+-compile(export_all).
+-include_lib("stdlib/include/qlc.hrl").
+-define (SERVER, message_store).
+
+-record (chat_message, {addressee, body, created_on}).
+
+save_message (Addressee, Body) ->
+ global:send(?SERVER, {save_msg, Addressee, Body}).
+
+find_messages (Addressee) ->
+ global:send(?SERVER, {find_msgs, Addressee, self()}),
+ receive
+ {ok, Messages} ->
+ Messages
+ end.
+
+start () ->
+ server_util:start(?SERVER, {message_store, run, [true]}).
+
+stop () ->
+ server_util:stop(?SERVER).
+
+run (FirstTime) ->
+ if
+ FirstTime == true ->
+ init_store(),
+ run(false);
+ true ->
+ receive
+ {save_msg, Addressee, Body} ->
+ store_message(Addressee, Body),
+ run(FirstTime);
+ {find_msgs, Addressee, Pid} ->
+ Messages = get_messages(Addressee),
+ Pid ! {ok, Messages},
+ run(FirstTime);
+ shutdown ->
+ mnesia:stop(),
+ io:format("Shutting down...~n")
+ end
+ end.
+
+delete_messages (Messages) ->
+ F = fun () ->
+ lists:foreach(fun (Msg) -> mnesia:delete_object(Msg) end, Messages)
+ end,
+ mnesia:transaction(F).
+
+get_messages (Addressee) ->
+ F = fun () ->
+ Query = qlc:q([M || M <- mnesia:table(chat_message), M#chat_message.addressee =:= Addressee]),
+ Results = qlc:e(Query),
+ delete_messages(Results),
+ [Message#chat_message.body || Message <- Results]
+ end,
+ {atomic, Messages} = mnesia:transaction(F),
+ Messages.
+
+store_message (Addressee, Body) ->
+ F = fun () ->
+ {_, CreatedOn, _} = erlang:now(),
+ mnesia:write(#chat_message{addressee = Addressee, body = Body, created_on = CreatedOn})
+ end,
+ mnesia:transaction(F).
+
+init_store () ->
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ try
+ mnesia:table_info(chat_message, type)
+ catch
+ exit: _ ->
+ mnesia:create_table(chat_message, [{attributes, record_info(fields, chat_message)},
+ {type, bag},
+ {disc_copies, [node()]}])
+ end.
View
@@ -0,0 +1,25 @@
+-module (server_util).
+-compile(export_all).
+
+start (ServerName, {Module, Function, Args}) ->
+ global:trans({ServerName, ServerName}, fun
+ () ->
+ case global:whereis_name(ServerName) of
+ undefined ->
+ Pid = spawn(Module, Function, Args),
+ global:register_name(ServerName, Pid);
+ _ ->
+ ok
+ end
+ end).
+
+stop (ServerName) ->
+ global:trans({ServerName, ServerName}, fun
+ () ->
+ case global:whereis_name(ServerName) of
+ undefined ->
+ ok;
+ _ ->
+ global:send(ServerName, shutdown)
+ end
+ end).

0 comments on commit 3237f47

Please sign in to comment.