Erlang 如何调用唯一的注册gen_服务器进程?

Erlang 如何调用唯一的注册gen_服务器进程?,erlang,gen-server,Erlang,Gen Server,我是Erlang的新手,我正在尝试建立一个简单的游戏服务器学习目的 我有一个客户端控制器主管,负责创建多个客户端处理程序gen_服务器。我还有一个游戏控制器主管,负责创建多个游戏处理器gen_服务器 然后,一个游戏处理程序游戏表将与多个客户端处理程序玩家通信。我创建如下的客户端处理程序: client_handler.erl: start_link(ClientId, UniqueId) -> ClientHandlerId = utils:create_id(?MODUL

我是Erlang的新手,我正在尝试建立一个简单的游戏服务器学习目的

我有一个客户端控制器主管,负责创建多个客户端处理程序gen_服务器。我还有一个游戏控制器主管,负责创建多个游戏处理器gen_服务器

然后,一个游戏处理程序游戏表将与多个客户端处理程序玩家通信。我创建如下的客户端处理程序:

client_handler.erl:

    start_link(ClientId, UniqueId) ->
    ClientHandlerId = utils:create_id(?MODULE, UniqueId), //client_handler_0 

    State = #state{client_id = ClientId, client_handler_id = ClientHandlerId},

    gen_server:start_link({global, ClientHandlerId}, ?MODULE, State, []).
    start_link(ClientHandlerId, GameId, UniqueId) ->    

    GameHandlerId = utils:create_id(?MODULE, UniqueId), //game_handler_0

    State = #state{client_handler_id = ClientHandlerId, game_id = GameId, game_handler_id = GameHandlerId},

    gen_server:start_link({global, GameHandlerId}, ?MODULE, State, []).
    gen_server:cast(game_handler_0, {make_move, MoveData}). 
    game_handler_0:make_move(MoveData)
game_handler.erl:

    start_link(ClientId, UniqueId) ->
    ClientHandlerId = utils:create_id(?MODULE, UniqueId), //client_handler_0 

    State = #state{client_id = ClientId, client_handler_id = ClientHandlerId},

    gen_server:start_link({global, ClientHandlerId}, ?MODULE, State, []).
    start_link(ClientHandlerId, GameId, UniqueId) ->    

    GameHandlerId = utils:create_id(?MODULE, UniqueId), //game_handler_0

    State = #state{client_handler_id = ClientHandlerId, game_id = GameId, game_handler_id = GameHandlerId},

    gen_server:start_link({global, GameHandlerId}, ?MODULE, State, []).
    gen_server:cast(game_handler_0, {make_move, MoveData}). 
    game_handler_0:make_move(MoveData)
我的问题是,我想在客户机处理程序和游戏处理程序之间交谈,但他们都不知道他们的内部结构。目前我使用:

client_handler.erl:

    start_link(ClientId, UniqueId) ->
    ClientHandlerId = utils:create_id(?MODULE, UniqueId), //client_handler_0 

    State = #state{client_id = ClientId, client_handler_id = ClientHandlerId},

    gen_server:start_link({global, ClientHandlerId}, ?MODULE, State, []).
    start_link(ClientHandlerId, GameId, UniqueId) ->    

    GameHandlerId = utils:create_id(?MODULE, UniqueId), //game_handler_0

    State = #state{client_handler_id = ClientHandlerId, game_id = GameId, game_handler_id = GameHandlerId},

    gen_server:start_link({global, GameHandlerId}, ?MODULE, State, []).
    gen_server:cast(game_handler_0, {make_move, MoveData}). 
    game_handler_0:make_move(MoveData)
这很有效。但是,我想使用:

client_handler.erl:

    start_link(ClientId, UniqueId) ->
    ClientHandlerId = utils:create_id(?MODULE, UniqueId), //client_handler_0 

    State = #state{client_id = ClientId, client_handler_id = ClientHandlerId},

    gen_server:start_link({global, ClientHandlerId}, ?MODULE, State, []).
    start_link(ClientHandlerId, GameId, UniqueId) ->    

    GameHandlerId = utils:create_id(?MODULE, UniqueId), //game_handler_0

    State = #state{client_handler_id = ClientHandlerId, game_id = GameId, game_handler_id = GameHandlerId},

    gen_server:start_link({global, GameHandlerId}, ?MODULE, State, []).
    gen_server:cast(game_handler_0, {make_move, MoveData}). 
    game_handler_0:make_move(MoveData)
因此,我可以为每个模块构建单独的API:s,只使用-export函数。这可能吗

致以最良好的祝愿, xqtr


编辑:输入错误是的,以这种方式抽象出实现细节被认为是一种良好的做法。只需将cast调用移动到game_handler.erl中的函数中,类似于:

make_move(UniqueId, MoveData) ->
    GameHandlerId = utils:create_id(?MODULE, UniqueId),
    gen_server:cast(GameHandlerId, {make_move, MoveData}).

并导出make_move/2。或者忘记UniqueId,直接将GameHandlerId传递给make_move函数。

Hi@legoscia,谢谢您的回复!将有两个独特的客户端处理程序和独特的游戏处理程序。客户端控制器将创建一个唯一的客户端处理程序,例如“Client\u handler\u 5”。然后,这个注册的原子将被传递给游戏控制器,游戏控制器将创建一个独特的游戏处理程序,比如“Game_handler_22”。我是否能够通过在客户端处理程序中创建一个函数(如connectGameHandlerId)来连接客户端处理程序,然后在游戏处理程序中使用:client\u handler\u 5:connectgame\u handler\u 22调用它?我是否必须在gen_服务器:start_链接中全局注册名称?