简体   繁体   English

查找注册过程Erlang

[英]Find registered process Erlang

So I am trying to make a chat system between two clients and a server in erlang. 因此,我尝试在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. 但是,当客户端请求与另一个客户端聊天时,它将进入findUser()函数,并在注册列表中查找目标用户名是否存在。 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. 由于Erlang不维护任何全局状态,因此userList变量将在checkUser/2的结尾处被破坏。

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). Erlang的内置ets( http://www.erlang.org/doc/man/ets.html )是一个开始寻找的好地方(还有dets和mnesia)。

You can also pass the list to and from the clients and the checkUser/2 function. 您还可以在客户端和checkUser/2函数之间checkUser/2传递列表。

I second what dethtron5000 wrote, however I wanted to point out that this the exact scenario that OTP gen_server is trying to solve. 我仅次于dethtron5000编写的内容,但是我想指出的是,这是OTP gen_server试图解决的确切情况。 You can keep the userList in the state between requests and use the gen_server API to handle instantiation and incoming messages. 您可以将userList保持在userList请求之间的状态,并使用gen_server API处理实例化和传入消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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