erlang网络库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.4 KiB

  1. -module(ntSslListener).
  2. -include("eNet.hrl").
  3. -include("ntCom.hrl").
  4. -compile(inline).
  5. -compile({inline_size, 128}).
  6. -export([
  7. start_link/4
  8. , getOpts/1
  9. , getListenPort/1
  10. , init_it/3
  11. , system_code_change/4
  12. , system_continue/3
  13. , system_get_state/1
  14. , system_terminate/4
  15. ]).
  16. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% genActor start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  17. -spec(start_link(atom(), atom(), inet:port_number(), [listenOpt()]) -> {ok, pid()} | ignore | {error, term()}).
  18. start_link(ListenName, AptSupName, Port, ListenOpts) ->
  19. proc_lib:start_link(?MODULE, init_it, [ListenName, self(), {AptSupName, Port, ListenOpts}], infinity, []).
  20. init_it(Name, Parent, Args) ->
  21. case safeRegister(Name) of
  22. true ->
  23. process_flag(trap_exit, true),
  24. modInit(Parent, Args);
  25. {false, Pid} ->
  26. proc_lib:init_ack(Parent, {error, {already_started, Pid}})
  27. end.
  28. -spec system_code_change(term(), module(), undefined | term(), term()) -> {ok, term()}.
  29. system_code_change(State, _Module, _OldVsn, _Extra) ->
  30. {ok, State}.
  31. -spec system_continue(pid(), [], {module(), atom(), pid(), term()}) -> ok.
  32. system_continue(_Parent, _Debug, {Parent, State}) ->
  33. loop(Parent, State).
  34. -spec system_get_state(term()) -> {ok, term()}.
  35. system_get_state(State) ->
  36. {ok, State}.
  37. -spec system_terminate(term(), pid(), [], term()) -> none().
  38. system_terminate(Reason, _Parent, _Debug, _State) ->
  39. exit(Reason).
  40. safeRegister(Name) ->
  41. try register(Name, self()) of
  42. true -> true
  43. catch
  44. _:_ -> {false, whereis(Name)}
  45. end.
  46. modInit(Parent, Args) ->
  47. case init(Args) of
  48. {ok, State} ->
  49. proc_lib:init_ack(Parent, {ok, self()}),
  50. loop(Parent, State);
  51. {stop, Reason} ->
  52. proc_lib:init_ack(Parent, {error, Reason}),
  53. exit(Reason)
  54. end.
  55. loop(Parent, State) ->
  56. receive
  57. {system, From, Request} ->
  58. sys:handle_system_msg(Request, From, Parent, ?MODULE, [], {Parent, State});
  59. {'EXIT', Parent, Reason} ->
  60. terminate(Reason, State);
  61. Msg ->
  62. case handleMsg(Msg, State) of
  63. kpS ->
  64. loop(Parent, State);
  65. {ok, NewState} ->
  66. loop(Parent, NewState);
  67. {stop, Reason} ->
  68. terminate(Reason, State),
  69. exit(Reason)
  70. end
  71. end.
  72. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% genActor end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  73. -record(state, {
  74. listenAddr :: inet:ip_address()
  75. , listenPort :: inet:port_number()
  76. , lSock :: inet:socket()
  77. , opts :: [listenOpt()]
  78. }).
  79. init({AptSupName, Port, ListenOpts}) ->
  80. TcpOpts = ?getLValue(tcpOpts, ListenOpts, []),
  81. %% Don't active the socket...
  82. case gen_tcp:listen(Port, lists:keystore(active, 1, TcpOpts, {active, false})) of
  83. {ok, LSock} ->
  84. AptCnt = ?getLValue(aptCnt, ListenOpts, ?AptCnt),
  85. ConMod = ?getLValue(conMod, ListenOpts, undefined),
  86. ConArgs = ?getLValue(conArgs, ListenOpts, undefined),
  87. startAcceptor(AptCnt, LSock, AptSupName, ConMod, ConArgs),
  88. {ok, {LAddr, LPort}} = inet:sockname(LSock),
  89. % ?ntInfo("success to listen on ~p ~n", [Port]),
  90. {ok, #state{listenAddr = LAddr, listenPort = LPort, lSock = LSock, opts = [{acceptors, AptCnt}, {tcpOpts, TcpOpts}]}};
  91. {error, Reason} ->
  92. ?ntErr("failed to listen on ~p - ~p (~s) ~n", [Port, Reason, inet:format_error(Reason)]),
  93. {stop, Reason}
  94. end.
  95. handleMsg({'$gen_call', From, miOpts}, #state{opts = Opts} = _State) ->
  96. gen_server:reply(From, Opts),
  97. kpS;
  98. handleMsg({'$gen_call', From, miListenPort}, #state{listenPort = LPort} = _State) ->
  99. gen_server:reply(From, LPort),
  100. kpS;
  101. handleMsg(_Msg, _State) ->
  102. kpS.
  103. terminate(_Reason, #state{lSock = LSock, listenAddr = Addr, listenPort = Port}) ->
  104. ?ntInfo("stopped on ~s:~p ~n", [inet:ntoa(Addr), Port]),
  105. %% 关闭这个监听LSock 监听进程收到tcp_close 然后终止acctptor进程
  106. catch port_close(LSock),
  107. ok.
  108. startAcceptor(0, _LSock, _AptSupName, _ConMod, _ConArgs) ->
  109. ok;
  110. startAcceptor(N, LSock, AptSupName, ConMod, ConArgs) ->
  111. supervisor:start_child(AptSupName, [LSock, ConMod, ConArgs, []]),
  112. startAcceptor(N - 1, LSock, AptSupName, ConMod, ConArgs).
  113. -spec getOpts(pid()) -> [listenOpt()].
  114. getOpts(Listener) ->
  115. gen_server:call(Listener, miOpts).
  116. -spec getListenPort(pid()) -> inet:port_number().
  117. getListenPort(Listener) ->
  118. gen_server:call(Listener, miListenPort).