有意思的一段代码:
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 % [email protected] 58 [email protected] 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()代码必须全局固定。
这是服务端:
([email protected])131> ([email protected])131> messenger:start_server(). true ([email protected])132> ([email protected])132> ([email protected])132> messenger:logon(frank). logged_on true ([email protected])133> ([email protected])133> ([email protected])135> messenger:message(mini, "123.123.123."). list is now: [{<10396.45.0>,mini},{<0.333.0>,frank}] sent ok ([email protected])136> ([email protected])136>
这是客户端:
([email protected])2> messenger:logon(mini). true logged_on ([email protected])3> ([email protected])3> ([email protected])6> ([email protected])6> ([email protected])6> Message from frank: "123.123.123." ([email protected])6>
ending 。。。。。。
时间: 2024-08-26 07:41:18