tcperlranch

Implementing Long live tcp connection using ninenine ranch


I'm trying to implement a long live TCP connection with ninnenine ranch erlang library . But looking at the documentation i cannot see a way of doing that. Also i have written my own ranch protocol as shown below

   start_link(Ref, _Socket, Transport, Opts) ->
        Pid = spawn_link(?MODULE, init, [Ref, Transport, Opts]),
        {ok, Pid}.

    init(Ref, Transport, _Opts = []) ->
        {ok, Socket} = ranch:handshake(Ref),
        loop(Socket, Transport).

    loop(Socket, Transport) ->
        case Transport:recv(Socket, 0, 5000) of
          {ok, Data} when Data =/= <<4>> ->
          %% Transport:send(Socket, Data),
          io:format("~w Connction accpted~n", [Data]);
          _ -> ok
               %%, Transport:close(Socket)
        end.

as you can see i have commented the Transport:close(Socket) and i'm not sending any response to the client since Transsport:send(socket,Data) is also commented thinking that is was going to solve the problem but still, my connections where closing immediately as opened . i have a golang client shown below

package main
import (
    "fmt"
    "log"
    "net"

)

    func main(){
        conn, err := net.Dial("tcp", "localhost:5555")
                if err != nil {
                    fmt.Println(err)
                }
                fmt.Println(conn /*, i*/)
                conn.Write(XMLData)
                buffer := make([]byte, 10024)
                n, err := conn.Read(buffer)
                fmt.Println(buffer[:n])
                //conn.Close()

    }

i though it was a time out in ranch causing that. I searched and i found that in the ranch, in the the file src/ranch_tcp.erl , we have the function listen implemented as below

listen(Opts) ->
Opts2 = ranch:set_option_default(Opts, backlog, 1024),
Opts3 = ranch:set_option_default(Opts2, nodelay, true),
Opts4 = ranch:set_option_default(Opts3, send_timeout, 30000),
Opts5 = ranch:set_option_default(Opts4, send_timeout_close, true),
%% We set the port to 0 because it is given in the Opts directly.
%% The port in the options takes precedence over the one in the
%% first argument.
gen_tcp:listen(0, ranch:filter_options(Opts5, disallowed_listen_options(),
    [binary, {active, false}, {packet, raw}, {reuseaddr, true}])).

As you can see there is a timeout option specifically Opts5 Opts5 = ranch:set_option_default(Opts4, send_timeout_close, true) and Opts4 Opts4 = ranch:set_option_default(Opts3, send_timeout, 30000),.I disabled them but still not working . So what am i supposed to do to have a long live tcp connection using ranch.


Solution

  • Your protocol implementation has a flaw

    loop(Socket, Transport) -> case Transport:recv(Socket, 0, 5000) of {ok, Data} when Data =/= <<4>> -> %% Transport:send(Socket, Data), io:format("~w Connction accpted~n", [Data]); _ -> ok %%, Transport:close(Socket) end.

    You do not call the loop/2 recursively in any of your case clause branch, thus the your protocol process dies when loop/2 returns bringing tcp connection down.