简体   繁体   中英

Find registered process Erlang

So I am trying to make a chat system between two clients and a server in erlang. I register each process when it goes online. But when a client requests to chat with another one it goes into the findUser() function and looks up in the registered list if the target username exists. But for some reason each clients username is not being added to the same registered list it looks like. How do I get all the new registered processes to get into the same list?

Server side:

-module(hw5server).
-export([start/0, checkUser/2, append/2, findUser/2]).

start() -> spawn(fun loop/0).

findUser(RequestorPid, Receiver) ->
    Reqmessage = io:format("~p would like to chat with you. Press 1 to accept or 2 to decline: ", [RequestorPid]),
    Pid2 = whereis(erlang:list_to_atom(Receiver)),
    Pid2 ! {Pid2, Reqmessage}.  ////////////MY ERROR!!!!

checkUser(Client,Username) ->
    case {lists:member(Username, [userList])} of
            {true} -> Message1 = io:format("Username taken.~n"),
                      Client ! {Message1};
            {false} -> append([userList], Username),
                       Message = io:format("You have been connected!~n"),
                       register(erlang:list_to_atom(Username), Client), //Registers the Client.
                       Client ! {Message}
    end.

append([List|T],User) -> [List|append(T,User)];
append([],User) -> User.

loop() ->
    receive
    {Client, Message} ->
            io:format("Server: received a message!~p~n",[Message]),
            Client ! {Message},
            loop()
    end.

Client side:

-module(hw5client).
-export([start/1,goOnline/2, loop/1, requestChatWith/2]).

start(Server) ->
    %Server = hw5server:start().
    spawn(hw5client, loop, [Server]),
    loop(Server).

goOnline(Client_Node,Username) ->
    hw5server:checkUser(Client_Node, Username),
    Request = io:get_line("Enter 1 to request chat or 2 to go offline: "),
    case {Request} of
            {"1\n"} -> Target = io:get_line("Please enter recipient's username: "),
                       requestChatWith(Client_Node, Target)
            end.

requestChatWith(Client_Node,Recipient) ->
    hw5server:findUser(Client_Node,Recipient).

loop(Server) ->
            Online = io:get_line("Enter 1 to go online: "),
            case {Online} of
                    {"1\n"} -> Name = io:get_line("Please enter a username: "),
                               goOnline(self(), Name)
            end,
            receive
            {_, Message} ->
                    io:format("~p",[Message]),
                    loop(Server)
end.

Your userList variable will be destroyed at the end of checkUser/2 since Erlang doesn't maintain any kind of global state.

If you want to store the list in memory you will need some way of persisting the list. Erlang's built-in ets ( http://www.erlang.org/doc/man/ets.html ) is a good place to start looking (there's also dets and mnesia).

You can also pass the list to and from the clients and the checkUser/2 function.

I second what dethtron5000 wrote, however I wanted to point out that this the exact scenario that OTP gen_server is trying to solve. You can keep the userList in the state between requests and use the gen_server API to handle instantiation and incoming messages.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM