Home AMX User Forum NetLinx Studio

Age ol' IP Question

Hi There,
I've been programming AMX for a while, no major problems but it occurred to me that I didn't quite understand what the AMX processor is doing under the hood in terms of IP Client Open. I've used it a lot for items such as switchers and projectors where I've opened the port, sent a msg and then closed it. I've also used a lot of udp for audio devices where I have just opened it up and away I went.

The item which is vexxing me is.... how to properly maintain a keep alive connection. Does anyone have a straightfoward answer? Is it a case of setting up a poll to try and open the port until it is definately open and then restart the poll if you receive an error or offline event? or otherwise????

Any clarification would be greatfully received!

Colin

Comments

  • ericmedleyericmedley Posts: 4,177
    Since we're talking about a port client we are by default at the mercy of the server device.

    So, for example, when you open a port on a web server (80) that conversation is very short. You open the port, send the "Get" command, the server sends its single response and closes the port. End of discussion.

    Devices that communicate on other ports may or may not keep the port open indefinitely.

    Media servers probably do keep their IP ports open for a much longer time as they will be sending the client asyncronous data all day long.

    When you open an IP port it doesn't time out fro your end. It times out from the server end.

    You could put a command in the 'offline' event of the data event that forces a reconnect to the device. However, this might make it made and lock it up. I've seen a few IP projectors and TVs that don't like to be banged on that much.
  • Thanks Eric,
    Seems like my polling procedure seems to be roughly in the right zone in that case. I can't see how a ip_client_open would open indefinately, especially if the device wasn't there or switched on I'd assume the amx would time out and give up.

    Speaking of time out? Would anyone know what the default is on an AMX? I've got my reconnect poll set at around 30 seconds but this still can generate some 'port busy' errors.
  • jjamesjjames Posts: 2,908
    I believe the default timeout [error 7] is 30 seconds and I don't think you can change it. You could however do an IP_CLIENT_CLOSE after 'x' number of seconds if the response you want is not received.

    [General Knowledge Plug]
    Regarding the reconnect - remember that the OFFLINE event only fires once. Just like you can only fall off of a horse once until you get back onto it, each failed attempt to get back on it means an error . . . ;) So, my suggestion would be to put a reconnect not only in the OFFLINE event but also in the ONERROR section (or create a timeline that will try to reconnect every so often - I prefer the former.) As I'm sure you know (more for others having an issue with IP connections), there are many different reasons as to why the processor won't connect - perhaps the server is gone, you've inputted a wrong address, or whatever, so I'd use the reason to your advantage. There are a few ONERROR event definitions floating around that you can just copy and paste in. You'd use DATA.NUMBER and act upon these definitions:
    2: General failure (out of memory)
    4: Unknown host
    6: Connection refused
    7: Connection timed out
    8: Unknown connection error
    9: Already closed
    14: Local port already used
    16: Too many open sockets
    17: Local Port Not Open
    

    Hope this helps (someone)!
    [/General Knowledge Plug]
  • a_riot42a_riot42 Posts: 1,624
    I didn't think there was a timout on a client. I have opened a port and waited far longer than 30 seconds and it has stayed open. I had a bug in my code where a GET command was empty, and the server just sat there waiting and my client stayed open until I closed it.

    What is closing the port is the server sending a FIN flag at the TCP level to initiate a close. Since you don't have access to that level you can't do anything other than open the port again or use more than one port. HTTP 1.1 supports persistent connections by default so if the server supports HTTP 1.1 it MAY keep the port open. You don't need to do anything special like use Keep-Alive or anything as persistent is the default behavior in HTTP 1.1.
    Paul
  • jjamesjjames Posts: 2,908
    a_riot42 wrote: »
    I didn't think there was a timout on a client. I have opened a port and waited far longer than 30 seconds and it has stayed open. I had a bug in my code where a GET command was empty, and the server just sat there waiting and my client stayed open until I closed it.

    I would agree that the server does handle the closing of a connection, but I'd argue that the master would know if it can or cannot reach a host, much like your browser. If I try to connect to www.i-love-amx-with-all-of-my-heart.com (which I'd guess does not exist), there is no server to say that it's done, right? So there there'd have to be some sort of mechanism in place to close the connection on the client's side I'd guess.

    I would suspect that your connection / port bug with an empty GET command was never closed because the server was counting down its TTL? I would imagine it would have eventually closed. I'm guessing at this point to be honest.

    Successful UDP connections I think stay open indefinitely, don't they?

    Perhaps some useful reading? http://amx.com/techsupport/techNote.asp?id=937
  • a_riot42a_riot42 Posts: 1,624
    jjames wrote: »
    If I try to connect to www.i-love-amx-with-all-of-my-heart.com (which I'd guess does not exist), there is no server to say that it's done, right? So there there'd have to be some sort of mechanism in place to close the connection on the client's side I'd guess.

    Yes a client can initiate a close of the socket after a timeout like your browser does.
    jjames wrote: »
    I would suspect that your connection / port bug with an empty GET command was never closed because the server was counting down its TTL? I would imagine it would have eventually closed. I'm guessing at this point to be honest.

    TTL is used to avoid networking loops and is a timeout of sorts, only it uses hosts rather than time so I don't think its that. I can't recall what the bug did, but it was likely an incomplete command and could have just been ignored.

    jjames wrote: »
    Successful UDP connections I think stay open indefinitely, don't they?

    UDP is considered connectionless. Its like speaking into a megaphone, if others hear you great, if not too bad.
    Paul
  • jjamesjjames Posts: 2,908
    a_riot42 wrote: »
    TTL is used to avoid networking loops and is a timeout of sorts, only it uses hosts rather than time so I don't think its that. I can't recall what the bug did, but it was likely an incomplete command and could have just been ignored.
    Ahh - ok . . . never knew exactly what it did, I thought it was timing. Anyway....back to the point - I'm fairly certain AMX does this and times the connection out itself if a host is not reachable.

    a_riot42 wrote: »
    UDP is considered connectionless. Its like speaking into a megaphone, if others hear you great, if not too bad.
    This made me chuckle. Curious though - wouldn't your description be more appropriate for multicast rather than UDP?
  • jjames wrote: »
    So, my suggestion would be to put a reconnect not only in the OFFLINE event but also in the ONERROR section (or create a timeline that will try to reconnect every so often - I prefer the former.)[/General Knowledge Plug]


    Hi jjames, I have to say I've used the former method once but had to abandon it. I had a host that refused connections when it was in a mood! That resulted in the processor going haywire because as soon as you opened a client the onerror event would trigger and then try and reopen the port!! I guess I could have placed a wait 301 in the onerror event to slow this down in hindsight.
  • viningvining Posts: 4,368
    For IP comms I like to use at least a 4 state variable with the states being:
    Disable
    Disco
    Pending
    Connected

    I usually do my connecting in a TL that runs for that particular piece of code and the time line runs if I need to be connected or need feedback, etc.

    In define start I disable the flag so I don't connect until a start up delay has timed out which is usually a minute or two after the program starts. Then I do my IP_CLIEN_OPEN and I set my flag to pending so that my code won't conitually try to open the port while the connection is in the process or attempting to contect. If I connect I set to connected but is I get an error I set my flag to disabled in the GET_IP_ERROR function where depending on the error type I may have a wait that after the wait period is over I'll set the flag to disco. IP_connect function won't do anything if I'm not in the "disco" state so no matter where my code calls to connect if I'm disabled, pending or connected I won't connect. Only if I'm disco'd. Some errors just stay disabled and an error message is sent, other will time out, repeat and continue to make attemps and some errors will go through a 3 strikes your out before it's permanently disabled and the error message is sent.

    With IP comms you really need flags to control the connection and re-connect events otherwise you'll piss off the master big time.
  • svTechsvTech Posts: 44
    One thing to be careful about a Keep-Alive connection. If you leave your connection open and the other end (i.e. the server) is ok with this, be sure to check what happens if you break the connection without a clean Close command. For instance, if you have to reboot the Netlinx or reload your code, I've seen devices that are acting as the server side, hang because they never saw an IP Connection Close. The far end might close eventually, but you don't want to have to wait 5 mins or whatever for the far end to timeout its own connection. This is why I try to, personally, stay away from Keep-Alive scenarios.
  • DHawthorneDHawthorne Posts: 4,584
    Just to round this discussion off, the Keep-Alive header command is just a suggestion to the server. Putting it in won't necessarily cause the server to keep the port open.
Sign In or Register to comment.