{?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的时候,会进行下面的处理: