在start_tcp/0中啟動了sd_tcp_listener_sup監控樹,並掛到sd_sup下。其後啟動的程序樹形關係如下:
這是遊戲伺服器啟動後使用observer觀察到的遊戲內程序關係圖,<0.68.0>為start_tcp/0啟動的sd_tcp_listener_sup監控樹,<0.70.0>為啟動的sd_tcp_listener程序。跟隨在sd_tcp_acceptor_sup後的十個程序為sd_tcp_acceptor程序。下面結合**詳細解釋一下tcp連線的建立過程。
sd_tcp_listener:掛在sd_tcp_listener_sup監控樹下的gen_server,用於監聽tcp埠。看下它的初始化函式init/1:
init() ->
process_flag(trap_exit, true),
case gen_tcp:listen(port, ?tcp_options) of
->
lists:foreach(fun (_) ->
= supervisor:start_child(
sd_tcp_acceptor_sup, [lsock])
end,
lists:duplicate(acceptorcount, dummy)),
;->
}end.
使用gen_tcp:listen/2監聽指定的埠,建立listensocket後通過lists:duplicate/2建立10個sd_tcp_acceptor_sup的子程序(此處傳入的acceptorcount為10)。
sd_tcp_acceptor:掛在sd_tcp_acceptor_sup下的gen_server,在建立listensocket之後被建立。看一下它的初始化函式init/1:
init() ->
gen_server:cast(self(), accept),
}.
程序在初始化的時候給自己cast了一條訊息,內容為原子accept,在hande_cast/2中接收到訊息後呼叫accept/1函式,函式的實現:
accept(state = #state) ->
case prim_inet:async_accept(lsock, -1) of
-> };
error -> , state}
end.
此處沒有使用gen_tcp:receive或者gen_tcp:accept來接收客戶端訊息,而是使用了prim_inet:async_accept/2來進行非同步的訊息接收,如果有訊息傳來,此時程序本身會收到一條格式為的訊息,由於程序為乙個gen_server,我們在handle_info裡面處理:
handle_info(}, state = #state) ->
case set_sockopt(lsock, sock) of
ok -> ok;
-> exit()
end,
start_client(sock),
accept(state);
建立了與客戶端的socket連線後,呼叫start_client/1函式:
start_client(sock) ->
= supervisor:start_child(sd_tcp_client_sup, ),
ok = gen_tcp:controlling_process(sock, child),
child ! .
在sd_tcp_client_sup監控樹下新建客戶端程序sd_reader,使用gen_tcp:controlling_process/2將建立的socket控制程序修改為該客戶端程序,並給該程序傳送一條的訊息,客戶端程序接收到這條訊息後便開始接手與客戶端的通訊。
之後sd_tcp_acceptor呼叫accept/1函式,進入迴圈等待客戶端連線的過程。
erlang遊戲原始碼 英雄遠征分析
erl p 1024000 k true smp disable name sd2 127.0.0.1 setcookie sd2 mnesia extra db nodes sd1 127.0.0.1 boot start sasl config log s sd gateway start ex...
英雄遠征Erlang原始碼分析(8) 怪物相關
與怪物相關的模組有三個 mod mon create.erl,mod mon active.erl,lib mon.erl mod mon create 建立負責建立怪物的程序,通過mod mon create create mon monid,scene,x,y,type 建立怪物程序 怪物建立程...
英雄遠征Erlang原始碼分析(9) 戰鬥流程解析
和戰鬥相關的模組有mod battle.erl 當玩家程序和怪物程序被建立的時候都會通過mod battle start link 建立乙個戰鬥程序。該戰鬥程序的state,用於儲存玩家上次出手或者使用技能的時機,用於cd的判斷 record state,開始戰鬥的時候,生成攻擊方和防守方的 bat...