一起做网游吧【9】:多服务器支持

       handle_call({register, IP, Port, Name, Enable, Maxuser, Pid, Fun}, _From, State) ->
    io:format("register server ~p ~n",[Name]),
    tcp_server:stop(Port),
    Client = #client{
      server_name = Name,
      server_port = Port,
      server_ip = IP,
      server = self()
     },
    {_, SocketPid} = case Enable of
                         true ->
                             F = fun(Sock) ->
                                         ?MODULE:loop(Sock, Client, Fun) end,
                             tcp_server:start_raw_server(Port, F, Maxuser, 2048);
                         Other ->
                             {ok, none}
                     end,
    case db:search(qlc:q([ServerData || ServerData <- mnesia:table(server),
                                        ServerData#server.name =:= Name,
                                        ServerData#server.port =:= Port,
                                        ServerData#server.ip =:= IP
                         ])) of 
        {atomic, [] } ->
            io:format("new server~n",[]),
            Server = #server {
              id = counter:bump(server),
              ip = IP,
              port = Port,
              name = Name,
              enable = Enable,
              maxuser = Maxuser,
              curuser = 0,
              pid = Pid,
              socketpid = SocketPid
              },
            mnesia:transaction(fun() ->
                                       mnesia:write(Server), Server#server.id end),
            ets:insert(State#state.serverstate, {SocketPid, Server});
        {atomic, [Server2]} ->
            Server = Server2#server {
                       ip = IP,
                       port = Port,
                       name = Name,
                       enable = Enable,
                       maxuser = Maxuser,
                       curuser = 0,
                       pid = Pid,
                       socketpid = SocketPid
                      },
            mnesia:transaction(fun() ->
                                       mnesia:write(Server), Server#server.id end),
            ets:insert(State#state.serverstate, {SocketPid, Server}),
            router:call({send_to_players, qlc:q([Player#player.id || Player <- mnesia:table(player),
                                                                             Player#player.socket /= none,
                                                                             Player#player.server_pid =:= none]),{?PP_SERVERLIST,[state({name,Name}, State)]}})
    end,
    {reply, ok, State};
       

该函数进行服务器的注册,对于在server.erl的全局接口来说,是server:registerserver。它首先停止正在运行在该端口上的进程,然后启动新的(Enable为true的情况下),然后再写入数据库中。你可以使用类似下面的语句来进行批量添加服务器:

       server:registerserver([{"test1", true, 3, 5000}, {"test1", true, 3, 5001}, {"test1", true, 3, 5002}, {"test2", true, 3, 5003}]).
       

上面的语句将启动两组服务器,test1有3个端口支持,test2只有一个端口支持。

使用下面的函数可以查看当前启动的服务器状态:

       state({name, Name}, State) ->
    case db:search(qlc:q([ServerDat#server.socketpid || ServerDat <- mnesia:table(server), 
                                                        ServerDat#server.name =:= Name, 
                                                        ServerDat#server.socketpid /= none])) of
        {atomic, []} ->
            {ok, Name, {{notrunning, {0, 0}},[]}};
        {atomic, ServerDat1}->
            {ok, Name, {{running, serverstate(ServerDat1, State, {0, 0})},serverstate1(ServerDat1, State)}}
    end.
       

serverstate函数和serverstate1函数分别统计服务器的简要信息和详细信息。简要信息仅包含服务器是否运行和当前及最大用户数,详细信息在简要信息的基础上添加了服务器IP和端口值。相对上面启动的服务器,调用下面的语句可以查看所有服务器的状态:

       server:serverstate(["test1", "test2"]).
       

或者:

       server:serverstate(serverstate:servernames()).
       

serverstate:servernames函数从数据库中获得所有的服务器名称(可能包括已经被彻底关闭的),动态的停止一个服务器,则是通过调用下面的实现:

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据