/project/pem/epem/src/_old/daemon_client.erl

http://phidget-erlang-manager.googlecode.com/ · Erlang · 186 lines · 93 code · 44 blank · 49 comment · 0 complexity · 4ed4585c8026e0983f7a3f5e9a28b4e3 MD5 · raw file

  1. %% Author: Jean-Lou Dupont
  2. %% Created: 2009-06-23
  3. %% Description: Module for communicating with the daemon
  4. %%
  5. %% SUBSCRIPTIONS:
  6. %% ==============
  7. %%
  8. %% {to_daemon, {MsgId, Msg}}
  9. %% {management_port, Port}
  10. %% {client, doconnect}
  11. %%
  12. %%
  13. %% MESSAGE GENERATED:
  14. %% ==================
  15. %% {from_daemon, Message} Message from Server side
  16. %% {management, open} Socket is open & ready
  17. %% {management, closed} Socket is closed
  18. %% {management, error} Socket cannot be opened
  19. %% {management, {txerror, MsgId}} Error transmitting message to Server
  20. %% {management, {txok, MsgId}} Transmission to Server OK
  21. -module(daemon_client).
  22. %%
  23. %% MACROS
  24. %%
  25. -define(TIMEOUT, 2000).
  26. -define(SUBS, [to_daemon, management_port, client]).
  27. %%
  28. %% Exported Functions
  29. %%
  30. -export([
  31. start_link/0,
  32. start_link/1,
  33. stop/0
  34. ]).
  35. -export([
  36. loop_connection/0,
  37. close_socket/0,
  38. close_socket/1,
  39. send_to_reflector/1,
  40. send_to_server/2,
  41. send_to_server/3
  42. ]).
  43. %% ======================================================
  44. %% API Functions
  45. %% ======================================================
  46. start_link()->
  47. Pid = spawn_link(?MODULE, loop_connection, []),
  48. register(daemon_client, Pid),
  49. ?MODULE ! {sync,undefined, undefined},
  50. %%base:ilog(?MODULE,"Pid[~p]~n",[Pid]),
  51. {ok, Pid}.
  52. %% Once started, sends Msg to Recipient
  53. start_link({Recipient, Msg}) ->
  54. Pid = spawn_link(?MODULE, loop_connection, []),
  55. register(daemon_client, Pid),
  56. ?MODULE ! {sync,Recipient, Msg},
  57. %%base:ilog(?MODULE,"Pid[~p]~n",[Pid]),
  58. {ok, Pid}.
  59. stop() ->
  60. daemon_client ! stop.
  61. %% ======================================================
  62. %% Local Functions
  63. %% ======================================================
  64. loop_connection() ->
  65. receive
  66. %% When we need to notify a root proc of our progress
  67. {sync, Recipient, Msg} ->
  68. put(root_proc, Recipient),
  69. base:send_ready_signal(daemon_client, Recipient, Msg);
  70. %% All modules are ready... let's sync
  71. %% to the Reflector
  72. mods_ready ->
  73. reflector:sync_to_reflector(?SUBS),
  74. ok;
  75. %% We are subscribed... final sync to the root proc
  76. {from_reflector, subscribed} ->
  77. RootProc=get(root_proc),
  78. %%base:send_on_count(RootProc, Msg, CountVar, TargetCount)
  79. base:send_synced_signal(daemon_client, RootProc),
  80. ok;
  81. {management_port, Port} ->
  82. put(management_port, Port);
  83. stop ->
  84. close_socket(),
  85. exit(ok);
  86. %% Starts a connection towards the Server
  87. {client, doconnect} ->
  88. close_socket(),
  89. Port=get(management_port),
  90. {Code, Socket} = gen_tcp:connect("localhost", Port, [binary, {active, true}, {packet, 2}], ?TIMEOUT),
  91. case Code of
  92. ok ->
  93. put(socket, Socket),
  94. reflector:send_sync(daemon_client, management, open, ?SUBS);
  95. _ ->
  96. put(socket, undefined),
  97. reflector:send_sync(daemon_client, management, error, ?SUBS)
  98. end;
  99. {to_daemon, {MsgId, Msg}} ->
  100. send_to_server(MsgId, Msg);
  101. %% From socket
  102. {tcp, _Sock, Data} ->
  103. Message = binary_to_term(Data),
  104. send_to_reflector(Message);
  105. %% From socket
  106. {tcp_closed, _Sock} ->
  107. put(socket, undefined),
  108. reflector:send_sync(daemon_client, management, closed, ?SUBS)
  109. %%after ?TIMEOUT ->
  110. %%reflector:sync_to_reflector(?SUBS)
  111. end,
  112. loop_connection().
  113. close_socket() ->
  114. Socket=get(socket),
  115. close_socket(Socket).
  116. close_socket(undefined) ->
  117. ok;
  118. close_socket(Socket) ->
  119. gen_tcp:close(Socket),
  120. put(socket, undefined).
  121. send_to_reflector({MsgType, Msg}) ->
  122. reflector:send_sync(daemon_server, MsgType, Msg, ?SUBS);
  123. send_to_reflector(Message) ->
  124. base:elog(?MODULE, "INVALID FORMAT: Message[~p]~n", [Message]).
  125. %% Send a message over the socket connection
  126. %% to the server side. The MsgId field is used
  127. %% to correlate a status message back to the
  128. %% subscriber of this Client interface.
  129. send_to_server(MsgId, Msg) ->
  130. Socket=get(socket),
  131. send_to_server(Socket, MsgId, Msg).
  132. send_to_server(undefined, MsgId, _Msg) ->
  133. reflector:send_sync(daemon_client, management, {txerror, MsgId}, ?SUBS);
  134. send_to_server(Socket, MsgId, Msg) ->
  135. Coded = term_to_binary(Msg),
  136. case gen_tcp:send(Socket, Coded) of
  137. ok ->
  138. reflector:send_sync(daemon_client, management, {txok, MsgId}, ?SUBS);
  139. {error,Reason} ->
  140. base:elog(?MODULE, "send_to_server: ERROR, Reason[~p], MsgId[~p] Msg[~p]~n", [Reason, MsgId, Msg]),
  141. reflector:send_sync(daemon_client, management, {txerror, MsgId}, ?SUBS)
  142. end.