【问题标题】:Difficulty adopting gen_server architecture in erlang在 erlang 中难以采用 gen_server 架构
【发布时间】:2017-12-18 05:03:53
【问题描述】:

我对 erlang 比较陌生,编写了以下模块:

-module(gserver).
-export([start1/0]).
-define(SERVER, gserver).

 start1() ->
 serv_util:start(?SERVER, 
                  { gserver, game_loop, 
                    [dict:new(), dict:new()]}).

serv_util:

-module(serv_util).
-export([start/2]).

 start(ServerName, {Module, Function, Args}) ->
 global:trans({ServerName, ServerName},
            fun() ->
                case global:whereis_name(ServerName) of
                    undefined ->        
                        Pid = spawn(Module, Function, Args),
                        global:register_name(ServerName, Pid);
                _ ->
                    ok
                end
            end).

然后我尝试将其置于 erlang 的 gen_server 架构下,如下所示:

-module(s_child).
-behaviour(gen_server).

 -export([start/0,stop/0]).
 -export([init/1, handle_call/3,handle_cast/2, terminate/2, 
  handle_info/2,code_change/3]).


 -import(gserver,[start1/0]).
 -import(gclient,[login/1]).



  start()->
  gserver:start1(),
  gen_server:start_link({global,?MODULE}, ?MODULE, [], []).

   stop()->
   gen_server:cast(?MODULE, {stop}).

  log_in(Name)->
  gen_server:call({global,?MODULE}, {login,Name,self()}).

  init(_Args) ->
   io:format("Hello started ~n"),
   {ok,_Args}.

   handle_call({login,Name},_From,State)->
   State,
   Reply=login(Name),
   {reply, Reply,State}.

但是当我按以下顺序调用它时

1)s_su​​p:start_link()。

你好,开始 {好的,}

2)s_child:log_in("Abhishek").

** exception exit: {{function_clause,
                        [{s_child,handle_call,
                             [{login,"Abhishek",<0.335.0>},
                              {<0.335.0>,#Ref<0.0.4.457>},
                              []],
                             [{file,"s_child.erl"},{line,61}]},
                         {gen_server,try_handle_call,4,
                             [{file,"gen_server.erl"},{line,615}]},
                         {gen_server,handle_msg,5,
                             [{file,"gen_server.erl"},{line,647}]},
                         {proc_lib,init_p_do_apply,3,
                             [{file,"proc_lib.erl"},{line,247}]}]},
                    {gen_server,call,
                        [{global,s_child},{login,"Abhishek",<0.335.0>}]}}
     in function  gen_server:call/2 (gen_server.erl, line 204)

而且我无法理解我的代码中第 61 行到底出了什么问题。在第 61 行的完整代码中存在以下代码:

handle_call(stop,  _From, State) ->

{stop, normal, ok, State};

即第一个 handle_call 出现在第 61 行

谁能帮帮我。

【问题讨论】:

    标签: erlang erlang-otp erlang-shell


    【解决方案1】:

    log_in 函数中,您将{login,Name,self()} 作为gen_server 调用传递,但handle_call 函数只需要{login,Name}。因此,由于没有匹配的子句,对handle_call 的调用失败。

    您不需要传递self(),因为您使用reply 功能来确保响应返回给调用者,因此只需修改log_in 以将{login,Name} 传递给gen_server:call

    【讨论】:

      【解决方案2】:

      Legoscia 的回答是对的。
      我推荐看看Understanding gen_server
      本文提供了有关使用 gen_server 的有用信息。

      【讨论】:

      • 是的,我绝对会查看@Pouriya 提供的有用链接。完全同意你的观点,我需要更好地了解 gen_server。谢谢
      猜你喜欢
      • 2017-10-14
      • 2011-08-09
      • 2014-11-09
      • 2011-10-08
      • 2016-08-09
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 2014-05-12
      相关资源
      最近更新 更多