Home AMX User Forum AMX General Discussion
Options

Netlinx as Server?

I'm setting up multiple servers on my Netlix master to accept conntections from customers for their daily check in and various notifications and getting rid of the email notification for reasons discussed elsewhere. I'm basically done with the approach I took and I'm now thinking I took the wrong approach even though it works.

Currently my master has 6 DPS for use as servers each on 1 of 6 ports. If a customer's master attempts a connection and the server port is in use it rolls to the next port in the array, etc and this works fine but last night before bed I thought I should just create, again 6 DPS for 6 servers on my master but all to use the same port. On start up call one server to listen on the one port say 1080. If a client connects I open a second server on poet 1080 to listen while the first server is busy and when the first server finishes I shut it down and leave the second server open. Always maintaining 1 server for listening even if other server have connections. At first I was thinking this would work and would be the logical way of doing this but the more I think of it the more I'm not sure if this would even work using the same ports on different DPS's. Does anyone know if this approach would work or not? I really don't want to waste time if it can't possibly work especially when my original method does work. The only draw back I see with my original method is I have to maitain 6 servers listening all the time which really seems a waste.

Any insight would be appreciated.

Comments

  • Options
    John NagyJohn Nagy Posts: 1,734
    It's logical that the Netlinx can't talk interactively with multiple clients on the same port with normal TCPIP. You probably can do it with UDP... but then you need more protocol to sort out who is talking.

    This may not help as it is still more complex, but I've seen TCP architectures for this purpose where one port is always listening for incoming connections, and the first thing once one arrives, the server assigns a new unique port and informs the incoming client where to go to continue, then drops and starts listening again for a new incoming contact. The starting port is never busy for long, and outside clients retry until serviced, informed, and moved to a new port just for their session.
  • Options
    viningvining Posts: 4,368
    John Nagy wrote: »
    It's logical that the Netlinx can't talk interactively with multiple clients on the same port with normal TCPIP. You probably can do it with UDP... but then you need more protocol to sort out who is talking.

    This may not help as it is still more complex, but I've seen TCP architectures for this purpose where one port is always listening for incoming connections, and the first thing once one arrives, the server assigns a new unique port and informs the incoming client where to go to continue, then drops and starts listening again for a new incoming contact. The starting port is never busy for long, and outside clients retry until serviced, informed, and moved to a new port just for their session.
    That's sort of why I was thinking it wouldn't work and hestitant to try just to fail. I suppose that wouldn't be too hard to impliment though. Keep one server listening on a fixed port and when a client connects send it a different port to use and marching orders to drop the connection and reconnect using the new port assignment while at the same time starting a server using the matching port to listen for it. That almost sounds like fun to do. Hmmm, how motivated do I feel?

    Thanks for the insight and the idea.
  • Options
    a_riot42a_riot42 Posts: 1,624
    You don't really care which server receives data do you? If not, why not have an array of servers listening on a TCP port?
    Paul
  • Options
    viningvining Posts: 4,368
    a_riot42 wrote: »
    You don't really care which server receives data do you? If not, why not have an array of servers listening on a TCP port?
    Paul
    No, not really since I parse out the "From: " line and "Subject: " line of the recieved traffic to determine how to handle it. Right now I have 6 servers listening on 6 different ports and when a client tries to connect on a port that's busy it drops that connection and then opens another connection on the next port in an array, etc until it finds a port that works. The down side is I need to maintain 6 servers (in this case) listening all the time when 99.9999% of the time there will be no clients looking to connect. This method is really the opposite of the other method where the primary listening server handles authetication (user/pass) and if approved assigns the client a port to re-connect to and send it's traffic. This seems a little cleaner and puts control on server side not the clients.

    Now what you're suggesting above, is that multiple servers using the same port? I had reservations about that being able to work and JN re-inforced that reservation. If it could then I could simply open 1 server for listening and start up another on the same port as clients connect but what JN said makes sense.

    Either way having the clients kick to a different port to send traffic after autheticating is pretty simple and basically the opposite of what I have now which works but being anal has its pittfalls and sometimes just working isn't good enough.
  • Options
    jweatherjweather Posts: 320
    vining wrote: »
    Any insight would be appreciated.

    Wouldn't it be faster to just try it?
    PROGRAM_NAME='test'
    DEFINE_DEVICE
    
    dvS1	= 0:3:0
    dvS2	= 0:4:0
    
    DEFINE_START
    
    IP_SERVER_OPEN(dvS1.PORT, 2001, IP_TCP)
    IP_SERVER_OPEN(dvS2.PORT, 2001, IP_TCP)
    
    DEFINE_EVENT
    
    DATA_EVENT[dvS1] {
        ONLINE: { SEND_STRING dvS1, 'S1 online' }
        OFFLINE: { 
    	SEND_STRING 0, 'S1 offline' 
    	IP_SERVER_OPEN(dvS1.PORT, 2001, IP_TCP)
        }
        STRING: { SEND_STRING 0, "'S1 RX: ', data.text" }
    }
    
    DATA_EVENT[dvS2] {
        ONLINE: { SEND_STRING dvS2, 'S2 online' }
        OFFLINE: { 
    	SEND_STRING 0, 'S2 offline' 
    	IP_SERVER_OPEN(dvS2.PORT, 2001, IP_TCP)
        }
        STRING: { SEND_STRING 0, "'S2 RX: ', data.text" }
    }
    

    Running this gives you two servers on port 2001. If you telnet to that port, you'll see "S1 online", and all the data from that telnet session will go to S1 (as seen in Diagnostics). Opening a second telnet session to the same port shows "S2 online", and all the data will go to S2. Both sessions are still active and talking to their respective ports. You can open and close up to two sessions with no problems. Increasing the number of DPS and IP_SERVER_OPEN calls increases the number of simultaneous sessions that can be open.

    TCP requires each incoming connection to have a unique tuple (remoteIP, remotePort, localPort). You can have two connections to port 2001 on your processor because each one has a different remote port. For instance, from my laptop at 192.168.1.198 to the processor at .195, here's my netstat output with two connections open:
      TCP    192.168.1.198:52618    192.168.1.195:2001     ESTABLISHED
      TCP    192.168.1.198:52712    192.168.1.195:2001     ESTABLISHED
    

    The two connections are from the same IP, but one is from source port 52618, the other is from 52712 -- this is how the two connections are kept differentiated. This would be a sad world if TCP could only handle one connection per server port per IP. Source ports are almost always randomly generated when you create a TCP connection (for instance, IP_CLIENT_OPEN doesn't let you pick your source port).
  • Options
    mpullinmpullin Posts: 949
    I can confirm jweather's observation. We do this for every job and it works great. If you open three servers, it's not possible to predict which one will "pick up" when an incoming request comes in, but as long as you remember to re-open the servers when the connection is closed, the connections will always get handled.

    If you wanted, you could use a global variable to keep track of the number of connections, open one more server than you want there to be possible connections, and if the maximum number of connections has been reached, have the server tell the client "maximum connections reached" and hang up right away.

    I use a DEV array for all my sockets, they are all treated the same (because you don't know what order they will pick up incoming connections in). GET_LAST can be used if you need to keep track of state for a connection.
  • Options
    viningvining Posts: 4,368
    Ok so the simple method can work which makes it a tad bit easier. I think I'll still go with the approach that I had my reservations about in the OP, having 6 DPS reserved for use as servers and all will use the same port. On start up I'll start just 1 server and when a client connects to it, I'll simply open another to listen for additinal clients and just try to keep 1 free for listening at all times unless all 6 have clients (will never happen).

    Thanks guys! Wish I gave this more thought before making my backwards appraoch module. :)

    What kind of overhead does an idle server place on the system anyway? I wouldn't suppose much but WTF do I know.
  • Options
    Joe HebertJoe Hebert Posts: 2,159
    John Nagy wrote: »
    It's logical that the Netlinx can't talk interactively with multiple clients on the same port with normal TCPIP.
    As jweather already pointed out that’s not true. If it was true port 1319 would have to be a magical port with supernatural powers.
  • Options
    John NagyJohn Nagy Posts: 1,734
    Joe Hebert wrote: »
    As jweather already pointed out that’s not true. If it was true port 1319 would have to be a magical port with supernatural powers.

    It's not? No Easter Bunny either?

    Thanks for clearing up these IP concepts.
  • Options
    Joe HebertJoe Hebert Posts: 2,159
    John Nagy wrote: »
    It's not? No Easter Bunny either?
    But there is a Santa Claus. I offer my dwindling bank account as proof.
  • Options
    a_riot42a_riot42 Posts: 1,624
    vining wrote: »
    Ok so the simple method can work which makes it a tad bit easier. I think I'll still go with the approach that I had my reservations about in the OP, having 6 DPS reserved for use as servers and all will use the same port. On start up I'll start just 1 server and when a client connects to it, I'll simply open another to listen for additinal clients and just try to keep 1 free for listening at all times unless all 6 have clients (will never happen).

    Thanks guys! Wish I gave this more thought before making my backwards appraoch module. :)

    What kind of overhead does an idle server place on the system anyway? I wouldn't suppose much but WTF do I know.

    By trying to simplify it you are making it more complicated it seems. Creating 6 sockets isn't going to hurt anything especially if they are idle most of the time. But why do you need 6 sockets if the traffic is so rare? One socket would most likely do unless you have so much traffic that connections are getting missed due to the few moments the socket is unavailable after closing but before opening. If you look at the Kaleidescape module, all traffic is through one port and serves 32 players and 32 touch panels I believe.
    Paul
  • Options
    viningvining Posts: 4,368
    a_riot42 wrote: »
    By trying to simplify it you are making it more complicated it seems. Creating 6 sockets isn't going to hurt anything especially if they are idle most of the time. But why do you need 6 sockets if the traffic is so rare? One socket would most likely do unless you have so much traffic that connections are getting missed due to the few moments the socket is unavailable after closing but before opening. If you look at the Kaleidescape module, all traffic is through one port and serves 32 players and 32 touch panels I believe.
    Paul
    This wouldn't be the 1st time I've over complicated things. Remember I'm anal w/ OCD. :)

    All my clients will be sending their daily sitrep at midnight so I want to have enough servers available so they don't have to keep trying until the server is free since masters tend to hand a bit while IP connections are pending or timing out. Also by creating a module for 6 servers I can easily scale it either way, up or down and right now since some of my daily logs are over 40 kbytes I'm just trying to create an architecture that has flexability so I don't have to do this a 3rd time and since I don't really know what I'm doing I figure I'd over design it. Besides I don't get paid for writing code so there's no one to yell at me for wasting time. :)
Sign In or Register to comment.