Implementing a re-connecting socket

35 views
Skip to first unread message

Jörg Krause

unread,
Jan 18, 2017, 11:52:39 AM1/18/17
to luvit
Hi,

I am trying to implement a client which tries to reconnect to server if, for whatever reason, is not available sometimes. My application is about piping the stdout of arecord to a TCP socket on a server. The application works fine, but is not bullet-proof if the server is not ready or is restarted. I want the client to reconnect to the server, without the need of a process monitor on the client side.

I found a similar nodejs example: https://gist.github.com/sio2boss/6334089

local spawn = require('childprocess').spawn
local net = require('net')

local args = {
  "-M",
  "-D", "hw:0,1",
  "-t", "raw",
  "-c", "2",
  "-r", "48000",
  "-f", "S16_LE",
}

local sock
sock = net.Socket:new()

local function doConnect()
  print("Connecting...")

  sock:connect(1234, '192.168.1.157')
end

local function onConnect()
  print("Connected")
  local arecord

  arecord = spawn("arecord", args)

  arecord:on("error", function(err)
    print("Spawn error:", err)
  end)
  arecord:on("exit", function(exit_status)
    print("Exit with " .. exit_status)
  end)

  arecord.stdout:pipe(sock)
  arecord.stderr:pipe(sock)
end

local function onError(err)
  print("Socket error:", err)
  if err == 'ECONNREFUSED' then
    sock:setTimeout(1000, doConnect)
  elseif err == 'EPIPE' then        
    sock:setTimeout(1000, doConnect)   
  end                               
end  
   
sock:on("connect", onConnect)
sock:on("error", onError)    
                         
doConnect()


The client tries one time to reconnect, but not more:

# luvit client.lua 
Connecting...
Socket error: ECONNREFUSED
Connecting...

Any idea what is wrong with my code?

Best regards,
Jörg Krause

Ryan Phillips

unread,
Jan 29, 2017, 2:04:42 PM1/29/17
to lu...@googlegroups.com, joerg....@embedded.rocks
Hey Jörg,

In your doConnect function you will want to instantiate a new socket there. You can't reuse the same socket instance.

Regards,
Ryan

--
You received this message because you are subscribed to the Google Groups "luvit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to luvit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jörg Krause

unread,
Feb 2, 2017, 3:12:04 AM2/2/17
to luvit, joerg....@embedded.rocks
Hey Ryan,


On Sunday, January 29, 2017 at 8:04:42 PM UTC+1, Ryan Phillips wrote:
Hey Jörg,

In your doConnect function you will want to instantiate a new socket there. You can't reuse the same socket instance.

I changed my client implementation and it seems to work now:

local fs = require('fs')
local spawn = require('childprocess').spawn
local net = require('net')

local args = {
  "-M",
  "-D", "record_left",
  "-t", "raw",
  "-c", "1",
  "-r", "48000",
  "-f", "S16_LE",
}

local function doConnect()
  local arecord
  local sock

  local ip = "192.168.0.101"
  local port = 1234

  if not ip or not port then return end

  print(string.format("Connecting to %s:%s", ip, port))
  sock = net.createConnection(port, string.format("%s", ip))

  sock:on("connect", function (err)
    if err then print("Connection error:", err) end
    print("Connected")

    arecord = spawn("arecord", args)

    arecord:on("error", function(err)
      print("Spawn error:", err)
    end)
    arecord:on("exit", function(exit_status)
      print("Exit with " .. exit_status)
      sock:setTimeout(1000, doConnect)
    end)

    arecord.stdout:on('data', function(data)
      sock:write(data)
    end)
    arecord.stderr:pipe(process.stderr)
  end)

  sock:on("error", function(err)
    if err then
      print("Socket error:", err)
      if arecord then
        arecord:kill('sigkill')
      else
        sock:setTimeout(1000, doConnect)
      end
    end
  end)
end

doConnect()

However, I am not sure if it is done correct. Maybe this implementation still has some flaws?

 
To unsubscribe from this group and stop receiving emails from it, send an email to luvit+un...@googlegroups.com.

Ryan Phillips

unread,
Feb 7, 2017, 1:46:14 PM2/7/17
to lu...@googlegroups.com, joerg....@embedded.rocks
That certainly looks like it should work.

To unsubscribe from this group and stop receiving emails from it, send an email to luvit+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages