15六/100
一起做网游吧【7】:服务器端注册和登录处理
B.服务器代码
抱歉的是,服务器目前的代码要比消息路由的代码还要多,因此只有核心:
服务器在启动过程中,通过下面的代码来检测数据库是否准备好了:
?Download server_src_server.erl
1 2 3 4 5 6 7 8 | mnesia:start(), case mnesia:wait_for_tables([counter], 100) of {timeout,_} -> io:format("ready create_tables~n",[]), schema:create_table([game,player,counter]); ok -> ok end, |
如果检查通过的话,会再次调用mnesia:wait_for_tables,因为在没有通过的时候,会自动创建数据库,虽然复杂了写,没什么坏处的。
服务器在初始化部分,会启动socket服务器的代码,让socket端口处于准备接收的状态。socket的代码没记错的话,Joe Armstrong在可容错服务器的教程中说了很多,当然,这里最后也会提供一份非常相似的。
下面的代码,应该是属于server部分,但却是在socket的进程中进行执行的:
?Download server_src_server.erl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | %% @spec loop(Socket,Client) -> ok %% @doc sokcet接口的回调函数,当socket接受到一个数据包时,将调用本函数. loop(Socket, Client) -> receive {tcp, Socket, Bin } -> case proto:read(Bin) of {?PP_REGISTER, Nick, Pass} -> case login:creat(Nick, Pass) of {ok, _} -> case login:login(Nick, Pass, self()) of { error, Error } -> io:format("login error: ~w: ~w: ~w : ~n", [Error, ?MODULE, ?LINE]), ok = ?tcpsend(Socket, {?ERROR_MESSAGE, Error}), loop(Socket, Client); {ok, Player} -> router:login(Player#player.id, self()), Client1 = Client#client{player = Player}, ok = ?tcpsend(Socket, {?PP_PID, Player#player.id}), loop(Socket, Client1) end; {error, Msg} -> ok = ?tcpsend(Socket, {?ERROR_MESSAGE, Msg}), loop(Socket, Client) end; {?PP_LOGIN, Nick, Pass } -> case login:login(Nick, Pass, self()) of { error, Error } -> io:format("login error: ~w: ~w : ~w: ~n", [Error, ?MODULE, ?LINE]), ok = ?tcpsend(Socket, {?ERROR_MESSAGE, Error}), loop(Socket, Client); {ok, Player} -> router:login(Player#player.id, self()), Client1 = Client#client{player = Player}, ok = ?tcpsend(Socket, {?PP_PID, Player#player.id}), loop(Socket, Client1) end; Other -> io:format("receive otherClient=~w:~w~n",[Client, Other]), loop(Socket, Client) end; {tcp_closed, Socket} -> ok; {packet, Packet } -> ok = ?tcpsend(Socket, Packet), loop(Socket, Client); Other-> io:format("server other:~w~n",[Other]), loop(Socket, Client) end. |
当从socket接收到数据包的时候,通过proto:read将数据包进行解析,变成erlang可以看的懂的结构。当接收到register的消息的时候,就创建一个新的用户,然后在服务器端模拟用户登录,将登录后的成功的消息发送给玩家,如果发生非常不幸的事情,比如用户名被占用了,则告诉玩家出错的消息。还有处理登录的消息,如果出错,会告诉玩家出错的消息。还有就是其他的消息了。erlang的设计非常的严密,每个函数都必须要有返回值,如果一旦发生不匹配,或者无法处理的消息,则很容易就引起执行该段代码的进程的终止。
原创文章,转载请注明: 转载自RIX 编程应该是快乐的
本文链接地址: 一起做网游吧【7】:服务器端注册和登录处理
文章的脚注信息由WordPress的wp-posturl插件自动生成