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

       {?PP_CONNECTSERVER, Code} ->
                    case db:search(qlc:q([Player || Player <- mnesia:table(player),
                                                    Player#player.code =:= Code,
                                                    Player#player.tag_server =:= Client#client.server_ip,
                                                    Player#player.tag_port =:= Client#client.server_port
                                         ])) of
                        {atomic, []} ->
                            ok = ?tcpsend(Socket, {?ERROR_MESSAGE, "some error, connect administrator"}),
                            ?MODULE:loop(Socket, Client);
                        {atomic, [Player]} ->
                            Player2 = Player#player{
                                        code = none,
                                        tag_server = none,
                                        tag_port = none,
                                        server_pid = Client#client.server_pid
                                       },
                            Client2 = Client#client{ player = Player2},
                            Result = case mnesia:transaction( fun() -> mnesia:write(Player2) end) of
                                         {atomic, ok} ->
                                             ok;
                                         Other ->
                                             io:format("some error, ~p~p:~p~n",[?MODULE, ?LINE, Other]),
                                             Other
                                     end,
                                    case Result of
                                        ok ->
                                            case serverstate:call({player_join, Client#client.server_pid, self()}) of
                                                {ok, join_self} ->
                                                    router:login(Player#player.id, self()),
                                                    ok = ?tcpsend(Socket, {?PP_JOINSERVER});
                                                {error, Msg} ->
                                                    io:format("some error, ~p~p:~p~n",[?MODULE, ?LINE, Msg]),
                                                    ok = ?tcpsend(Socket, {?ERROR_MESSAGE, "some error, connect administrator"})
                                            end;
                                        Other1 ->
                                            ok = ?tcpsend(Socket, {?ERROR_MESSAGE, "some error, connect administrator"})
                                    end,
                            ?MODULE:loop(Socket, Client2)
                    end;
       

首先使用code,ip,port进行用户的查找,如果没有找到的话,告诉客户端:“你丫骗谁呢,找我们老大去。”,找到的话,则提取用户信息。关于唯一性,上面也讨论了。由于是重新连接,在服务器人数非常多的时候,可能在极短的时间内,也会发生服务器当前用户排名的更改,因此,在重新连接的时候,不会进行服务器的排名,而是仅仅进行服务器的有效性检查就介入了:

       handle_call({player_join, Socket, Self}, From, State) ->
    Result = case ets:lookup(State#state.serverstate, Socket) of
                 [] ->
                     {error, "not find serve"};
                 [{_,Server}] ->
                     Server3 = Server#server {
                                 curuser = Server#server.curuser + 1
                                },
                     ets:insert(State#state.serverstate, {Socket, Server3}),
                     ServerState = state({name, Server3#server.name}, State),
                     send_event(State#state.eventhandle, [{state, [ServerState]}]),
                     router:call({send_to_players, qlc:q([Player#player.id || Player <- mnesia:table(player),
                                                                             Player#player.socket /= none,
                                                                             Player#player.socket /= Self,
                                                                             Player#player.server_pid =:= none]),{?PP_SERVERLIST,[ServerState]}}),
                     {ok, join_self}
             end,
    {reply, Result, State};
       

客户端要退出了,连接中断了,服务器需要知道是在哪一个服务器上的用户退出了,因此,在接收到tcp_closed的时候,会进行下面的处理:

发表评论

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