繁体   English   中英

在不同的终端窗口上运行Erlang程序时的异常

[英]Exceptions when running Erlang program on different terminal windows

我正在用Erlang开发一个简单的框架来处理2人回合制游戏。 代码如下:

-module(game).
-export([start_server/0,generate_server/0,add_player/0,remove_player/0]).


generate_server() ->
Table_num = 0,
Player_num = 0,
io:format("Server generated...~n", []),
io:format("The current number of tables is ~w~n", [Table_num]),
io:format("The current number of players is ~w~n", [Player_num]),
receive
    login ->
        io:format("A new player has connected!~n", []),
        New = Player_num + 1,
        io:format("The current number of players is ~w~n", [New]);
    logout ->
        io:format("You have beeen succesfully disconnected~n", [])
end.



start_server() ->
    io:format("Welcome player!~nInitializing game...~n", []),
    io:format("Generating server...~n", []),
    register(server,spawn(game, generate_server, [])).


add_player() ->
    server ! login.


remove_player() ->
    server ! logout.

运行此代码时,有两个主要问题:

  1. 当我执行add_player()然后执行remove_player()时,第二个函数崩溃,但出现异常
  2. 如果我在一个终端窗口上启动程序,然后在第二个终端窗口上执行add_player(),则会收到错误消息。 我应该怎么做才能在多个终端窗口上运行它?

任何帮助将不胜感激。

1 /您的服务器中没有环路。 当您启动它时,在进行一些打印后,它会等待receive语句。

收到登录消息后,将执行操作,然后完成服务器代码。 该进程死亡,并且未注册。 所有变量消失,虚拟机清理内存...

因此,稍后,由于您使用的名称不再注册,因此向服务器发送消息的任何进程都将崩溃。

为了使它起作用,您应该保留一个已连接播放器的列表(例如在列表中),并使用该列表作为参数来调用服务器循环。

generate_server(Tlist,Plist) ->
io:format("The current number of tables is ~w~n", [length(Tlist)]),
io:format("The current number of players is ~w~n", [length(Plist)]),
receive
    {login,Name} ->
        io:format("A new player ~p has connected!~n", [Name]),
        generate_server(Tlist,[Name|Plist]);
    {logout,Name} ->
        io:format("You have beeen succesfully disconnected~n", []),
        generate_server(Tlist,lists:delete(Name,Plist))
end.

而对generate_server的调用是由

register(server,spawn(game, generate_server, [[],[]]))

2 /为了在2个不同的节点之间使用erlang消息,您需要:

  • 共享相同的Erlang Coockie
  • 发现节点(例如使用netadm)
  • 获取服务器pid或使用golbal注册名称

请参见http://learnyousomeerlang.com/distribunomicon#alone-in-the-dark中的示例

您错过了服务器的loop主体。 由于服务器仅收到一条消息并退出,因此程序崩溃。 请考虑以下服务器的另一个版本:

generate_server() ->
    Table_num = 0,
    Player_num = 0,
    io:format("Server generated...~n", []),
    io:format("The current number of tables is ~w~n", [Table_num]),
    io:format("The current number of players is ~w~n", [Player_num]),
    loop([]).
loop(Players)-> receive {From,{login,PlayerId}} -> io:format("A new player has connected!~n", []), io:format("The current number of players is ~w~n", [New]), NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {login_failed,exists}, Players; false -> From ! {login_success,true}, [PlayerId|Players] end, loop(NewPlayers); {From,{logout,PlayerId}} -> NewPlayers = case lists:member(PlayerId,Players) of true -> From ! {logout,ok}, Players -- [PlayerId]; false -> From ! {logout,failed}, Players end,
loop(NewPlayers); _ -> loop(Players) end.
那里; 看起来好多了。

暂无
暂无

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

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