有意思的一段代码

有意思的一段代码:

  1 %%% Message passing utility.
  2 %%% User interface:
  3 %%% logon(Name)
  4 %%%     One user at a time can log in from each Erlang node in the
  5 %%%     system messenger: and choose a suitable Name. If the Name
  6 %%%     is already logged in at another node or if someone else is
  7 %%%     already logged in at the same node, login will be rejected
  8 %%%     with a suitable error message.
  9 %%% logoff()
 10 %%%     Logs off anybody at that node
 11 %%% message(ToName, Message)
 12 %%%     sends Message to ToName. Error messages if the user of this
 13 %%%     function is not logged on or if ToName is not logged on at
 14 %%%     any node.
 15 %%%
 16 %%% One node in the network of Erlang nodes runs a server which maintains
 17 %%% data about the logged on users. The server is registered as "messenger"
 18 %%% Each node where there is a user logged on runs a client process registered
 19 %%% as "mess_client"
 20 %%%
 21 %%% Protocol between the client processes and the server
 22 %%% ----------------------------------------------------
 23 %%%
 24 %%% To server: {ClientPid, logon, UserName}
 25 %%% Reply {messenger, stop, user_exists_at_other_node} stops the client
 26 %%% Reply {messenger, logged_on} logon was successful
 27 %%%
 28 %%% To server: {ClientPid, logoff}
 29 %%% Reply: {messenger, logged_off}
 30 %%%
 31 %%% To server: {ClientPid, logoff}
 32 %%% Reply: no reply
 33 %%%
 34 %%% To server: {ClientPid, message_to, ToName, Message} send a message
 35 %%% Reply: {messenger, stop, you_are_not_logged_on} stops the client
 36 %%% Reply: {messenger, receiver_not_found} no user with this name logged on
 37 %%% Reply: {messenger, sent} Message has been sent (but no guarantee)
 38 %%%
 39 %%% To client: {message_from, Name, Message},
 40 %%%
 41 %%% Protocol between the "commands" and the client
 42 %%% ----------------------------------------------
 43 %%%
 44 %%% Started: messenger:client(Server_Node, Name)
 45 %%% To client: logoff
 46 %%% To client: {message_to, ToName, Message}
 47 %%%
 48 %%% Configuration: change the server_node() function to return the
 49 %%% name of the node where the messenger server runs
 50 
 51 -module(messenger).
 52 -export([start_server/0, server/1, logon/1, logoff/0, message/2, client/2]).
 53 
 54 %%% Change the function below to return the name of the node where the
 55 %%% messenger server runs
 56 server_node() ->
 57 %    messenger@bill.
 58     franklinrhel@franklinrhel.
 59 %    erlang:node().
 60 
 61 %%% This is the server process for the "messenger"
 62 %%% the user list has the format [{ClientPid1, Name1},{ClientPid22, Name2},...]
 63 server(User_List) ->
 64     receive
 65         {From, logon, Name} ->
 66             New_User_List = server_logon(From, Name, User_List),
 67             server(New_User_List);
 68         {From, logoff} ->
 69             New_User_List = server_logoff(From, User_List),
 70             server(New_User_List);
 71         {From, message_to, To, Message} ->
 72 
73 server_transfer(From, To, Message, User_List), 74 io:format("list is now: ~p~n", [User_List]), 75 server(User_List) 76 end. 77 78 %%% Start the server 79 start_server() -> 80 register(messenger, spawn(messenger, server, [[]])). 81 82 %%% Server adds a new user to the user list 83 server_logon(From, Name, User_List) -> 84 %% check if logged on anywhere else 85 case lists:keymember(Name, 2, User_List) of 86 true -> 87 From ! {messenger, stop, user_exists_at_other_node}, %reject logon 88 User_List; 89 false -> 90 From ! {messenger, logged_on}, 91 [{From, Name} | User_List] 92 end. 93 94 %%% Server deletes a user from the user list 95 server_logoff(From, User_List) -> 96 lists:keydelete(From, 1, User_List). 97 98 %add user to the list 99 %%% Server transfers a message between user 100 server_transfer(From, To, Message, User_List) -> 101 %% check that the user is logged on and who he is 102 case lists:keysearch(From, 1, User_List) of 103 false -> 104 From ! {messenger, stop, you_are_not_logged_on}; 105 {value, {From, Name}} -> 106 server_transfer(From, Name, To, Message, User_List) 107 end. 108 109 %%% If the user exists, send the message 110 server_transfer(From, Name, To, Message, User_List) -> 111 %% Find the receiver and send the message 112 case lists:keysearch(To, 2, User_List) of 113 false -> 114 From ! {messenger, receiver_not_found}; 115 {value, {ToPid, To}} -> 116 ToPid ! {message_from, Name, Message}, 117 From ! {messenger, sent} 118 end. 119 120 %%% User Commands 121 logon(Name) -> 122 case whereis(mess_client) of 123 undefined -> 124
125 register(mess_client, 126 spawn(messenger, client, [server_node(), Name])); 127 _ -> already_logged_on 128 end. 129 130 logoff() -> 131 mess_client ! logoff. 132 133 message(ToName, Message) -> 134 case whereis(mess_client) of % Test if the client is running 135 undefined -> 136 not_logged_on; 137 _ -> mess_client ! {message_to, ToName, Message}, 138
139 ok 140 end. 141 142 %%% The client process which runs on each server node 143 client(Server_Node, Name) -> 144 {messenger, Server_Node} ! {self(), logon, Name}, 145 await_result(), 146 client(Server_Node). 147 148 client(Server_Node) -> 149
150 receive 151 logoff -> 152 {messenger, Server_Node} ! {self(), logoff}, 153 exit(normal); 154 {message_to, ToName, Message} -> 155156 {messenger, Server_Node} ! {self(), message_to, ToName, Message}, 157 await_result(); 158 {message_from, FromName, Message} -> 159 io:format("Message from ~p: ~p~n", [FromName, Message]) 160 end, 161 client(Server_Node). 162 163 %%% wait for a response from the server 164 await_result() -> 165 receive 166 {messenger, stop, Why} -> % Stop the client 167 io:format("~p~n", [Why]), 168 exit(normal); 169 {messenger, What} -> % Normal response 170 io:format("~p~n", [What]) 171 end.

其中

server_node()代码必须全局固定。

这是服务端:

(franklinrhel@franklinrhel)131> 
(franklinrhel@franklinrhel)131> messenger:start_server().
true
(franklinrhel@franklinrhel)132> 
(franklinrhel@franklinrhel)132> 
(franklinrhel@franklinrhel)132> messenger:logon(frank). 
logged_on
true
(franklinrhel@franklinrhel)133> 
(franklinrhel@franklinrhel)133> 
(franklinrhel@franklinrhel)135> messenger:message(mini, "123.123.123.").
list is now: [{<10396.45.0>,mini},{<0.333.0>,frank}]
sent
ok
(franklinrhel@franklinrhel)136> 
(franklinrhel@franklinrhel)136> 

这是客户端:

(macmini@franklinMacmini)2> messenger:logon(mini).
true
logged_on                   
(macmini@franklinMacmini)3> 
(macmini@franklinMacmini)3> 

(macmini@franklinMacmini)6> 
(macmini@franklinMacmini)6> 
(macmini@franklinMacmini)6> 
Message from frank: "123.123.123."
(macmini@franklinMacmini)6>

ending 。。。。。。

原文地址:https://www.cnblogs.com/andypeker/p/4678529.html