gen_tcp:connect 使用主管时将关闭

gen_tcp:connect will close when using supervisor

我有一个简单的 gen_server 连接到一个 tcp 端口,当我 运行 gen_server 直接:

erl -noshell -s ttest start

它工作正常,但是当我 运行:

erl -noshell -s tt_sup start_link

连接会立即关闭,如果我取消链接主管就可以了:

erl -noshell -s tt_sup start_shell

我如何 运行 我简单的 gen_tcp:connect (gen_server) 与主管?

主管:

-module(tt_sup).
-behaviour(supervisor).
-export([init/1, start_link/0, start_shell/0]).

start_link() ->
    io:format("Supervisor started with PID~p~n", [self()]),
    {ok, Pid} = supervisor:start_link(tt_sup, []),
    io:format("Supervisor PID=~p~n", [Pid]),
    {ok, Pid}.

start_shell() ->
    io:format("Supervisor started with PID~p~n", [self()]),
    {ok, Pid} = supervisor:start_link(tt_sup, []),
    io:format("Supervisor PID=~p~n", [Pid]),
    unlink(Pid),
    {ok, Pid}.

init(_Args) ->
    SupFlags = #{strategy => one_for_one},
    Child = [#{id => ttest, start => {ttest, start, []},
               restart => permanent, shutdown => brutal_kill,
               type => worker, modules => [ttest]}],
    {ok, {SupFlags, Child}}.

gen_server:

-module(ttest).
-export([start/0,init/1,handle_cast/2,handle_call/3,handle_info/2,terminate/2,connect/1]).
-behaviour(gen_server).



start() ->

       io:format("gen_server start id is ~p~n",[self()]),
       {ok,Pid} = gen_server:start_link({local,ttest},ttest,[],[]),
       io:format("gen_server id is ~p~n",[Pid]),
       connect(Pid),
       {ok,Pid}.



init(_Args) ->
        io:format("init id is ~p~n",[self()]),
        {ok,[]}.       
handle_call({tcp,Socket,Bin},_From,States) ->
        {reply,States,States}.
handle_info({tcp,Socket,Bin},States) ->
        io:format("got info msg"),
        {noreply,States}.

handle_cast({send,Msg},States) ->
        {reply,States}.

connect(I) ->
    io:format("connect id is ~p~n",[self()]),
    {ok,Socket} =gen_tcp:connect("localhost",6000,[binary,{active,true}]),
    gen_tcp:controlling_process(Socket,I).



terminate(shutdown, State) ->
    io:format("terminating"),
    ok.

运行 -s 的进程在没有更多代码可执行时以 normal 退出。主管接收到该信号并且由于它来自其父级,它退出(不管它是 normal),如 gen_server:terminate/2 中所述(supervisors 是 gen_servers 与 trap_exit 活跃):

Even if the gen_server process is not part of a supervision tree, this function is called if it receives an 'EXIT' message from its parent. Reason is the same as in the 'EXIT' message.

我没有测试过您的代码,但是如果您将 process_flag(trap_exit, true) 添加到 gen_server,您肯定会复制此行为。