Home AMX User Forum AMX General Discussion

Keep IP connection alive

Dear All,
I'm trying to establish an IP connection with an NX controller and an IP Amplifier. I have noticed that the amplifier is closing the connection after some period of time - about 20 seconds- and I should re connect the NX with it. It is not a big deal but some times there are commands missed if they are sent on that "disconnection" gap.
But when I'm doing the connection with any Microsoft network client ( in my case with PUTTY ), the connection is never missed which means that PUTTY is sending maybe something on the background that keeps the connection always alive.
How can I do that with the NX to always keep the connection alive ?
Below my sample code that checks the connection every 5 seconds :

DEFINE_DEVICE

dvSonyProj = 0:5:0

DEFINE_CONSTANT

IPCONN_DISCONNECTED = 0
IPCONN_CONNECTED = 1
IPCONN_TRYING = 2

TL_IP_POLL = 2
nSonyProj_PORT = 53595

DEFINE_VARIABLE

integer nConnectStatus[1] //1 IP devices
long tlPollingIntervals[] = { 5000 } // length of time between retrying to connect, every 5 sec

volatile dev nIP_Devices[] = { dvSonyProj}

volatile char nIP_Addresses[][15] = { '192.168.1.27' }

volatile char nIP_Names[][30] = { 'Sony Projector' }
volatile integer nIP_Ports[] = { nSonyProj_PORT }

define_function fnTCP_MaintainConnection(integer nDeviceIdx)
{
if(nConnectStatus[nDeviceIdx] == IPCONN_DISCONNECTED)
{
ip_client_open(nIP_Devices[nDeviceIdx].port,nIP_Addresses[nDeviceIdx],nIP_Ports[nDeviceIdx],IP_TCP)
send_string 0:0:0, "'fnTCP_ClientConnect(): Attempting To Connect with...',nIP_Names[nDeviceIdx]"
}
}

DEFINE_START

nConnectStatus[1] = IPCONN_DISCONNECTED

timeline_create(TL_IP_POLL,tlPollingIntervals,length_array(tlPollingIntervals),TIMELINE_ABSOLUTE,TIMELINE_REPEAT)

DEFINE_EVENT

data_event[nIP_Devices]
{
online:
{
stack_var integer nDeviceIdx

        nDeviceIdx = get_last(nIP_Devices)

        nConnectStatus[nDeviceIdx] = IPCONN_CONNECTED
        send_string 0:0:0, "'fnTCP_ClientConnect(): NOW CONNECTED TO DEVICE...',nIP_Names[nDeviceIdx]" 
    }
offline:
    {
        stack_var integer nDeviceIdx

        nDeviceIdx = get_last(nIP_Devices)

        ip_client_close(nIP_Devices[nDeviceIdx].port)
        nConnectStatus[nDeviceIdx] = IPCONN_DISCONNECTED
        send_string 0:0:0, "'fnTCP_ClientConnect(): NOW DISCONNECTED FROM DEVICE...',nIP_Names[nDeviceIdx]"
    }
string:
    {
        stack_var integer nDeviceIdx

        nDeviceIdx = get_last(nIP_Devices)

        send_string 0, "'String received from ',nIP_Names[nDeviceIdx],': ',data.text, $0A"
    }

}

timeline_event[TL_IP_POLL]
{
switch(timeline.sequence)
{
case 1: fnTCP_MaintainConnection(1)
}
}

Thanks,
George

Comments

  • John NagyJohn Nagy Posts: 1,733
    edited October 2019

    Several opinions on this... mine is to open the port only and each time you have a command. Takes miliseconds, no delay you can detect. If the port is already open from a prior connection, you'll see an error, already open, and you really should not care... your command will work. No need to ever command the port closed. No reason to hold the port open 24/7/365 just in case you might want to send a command.

    This isn't ideal for something that may be interactive, that is, sending un-prompted feedback, where you need an uninterrupted connection. Not the case with a projector.

  • If an IP device closes it connection, it usually does so 'x' seconds after it received the last command. If you want the connection kept open, to receive unsolicited responses from the device, send it some request before it closes the connection.
    So in your function 'TCP_MaintainConnection', add something to send to the amplifier, maybe power state, or serial number, or mac address, or whatever. You don't have to parse the response if you don't want, it's only there to keep the connection open. Just make sure the connection is really established before you send anything and I would check the timing: If 15 seconds is good, use that instead of 5 seconds.

  • John NagyJohn Nagy Posts: 1,733
    edited October 2019

    Doing an endless keepalive process is overkill for devices that get a command maybe a couple times a week. Times dozens or hundreds of such devices, and you are spinning lots of cycles for nothing.

  • @John Nagy said:
    Doing an endless keepalive process is overkill for devices that get a command maybe a couple times a week. Times dozens or hundreds of such devices, and you are spinning lots of cycles for nothing.

    Not sure what the point is you're trying to make. Sometimes you just need an IP connection to stay open. For instance, a media player type device (own example) that sends back info about transport state (play, stop, etc.) and content info.
    And of course, be smart about the keepalive function. Only use it when the device is actually beeing used, or at least shut it down on system power down. But that is an exercise left to the reader... :)

  • Hi,

    You can also try to execute IP_Client_Open from offline event. If it's not the case that the device was disconnected physically, it should reconnect.

  • John NagyJohn Nagy Posts: 1,733

    @MichalMoraszczyk said:
    You can also try to execute IP_Client_Open from offline event. If it's not the case that the device was disconnected physically, it should reconnect.

    Do this with caution. If the device will not connect, you don't want all your resources soaked up in perpetual instantaneous retries. Consider a maximum retry count or a timeline to retry on a conservative schedule.

  • @John Nagy said:
    Do this with caution. If the device will not connect, you don't want all your resources soaked up in perpetual instantaneous retries. Consider a maximum retry count or a timeline to retry on a conservative schedule.

    Absolutely, you're right.

Sign In or Register to comment.