closing socket

Posted on
Wed Feb 14, 2018 5:34 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

closing socket

I open a tcpip socket at startup of plugin and at the end it is closed()
issue:
when restarting plugin it takes about 15 seconds before the open works again, .
(12345 is the port# used)

open:
Code: Select all
socketServer = ThreadedTCPServer((192.168.1.x,12345), ThreadedTCPRequestHandler)
testing after socketServer is done with
/usr/sbin/lsof -i tcp:12345
shows nothing open

as soon as /usr/sbin/lsof -i tcp:12345 shows a port (that takes 15 seconds)
Code: Select all
TCPserverHandle = threading.Thread(target=socketServer.serve_forever)
TCPserverHandle.daemon =True # don't hang on exit
TCPserverHandle.start()
works fine.


closing is done like this at the end of plugin works w/o problem:
Code: Select all
        if self.socketServer is not None: 
            self.socketServer.shutdown()
            self.socketServer.server_close()
            indigo.server.log( u"stopped tcpip stack")

Also works when the plugin is disabled and then enabled, but when plugin gets restarted (by itself).. looks like there is still something open, but not visible and it takes OSX ~ 15 secs to finally close the socket.

==> is there anything that can be done to force a close ie give some parameters to elf.socketServer.shutdown()
tried
Code: Select all
self.socketServer.shutdown(socket.SHUT_RDWR)
but that complains that 2 args are given, while one is expected ..


Karl

Posted on
Wed Feb 14, 2018 7:24 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: closing socket

It can be a little tricky. I use BaseHTTPServer myself and I had hang problems until I did multi-threading for the server itself and started it up the server in a different thread than the plugin as well.

Code: Select all
def run (self, port, username = None, password = None):
      self.myThread = threading.Thread(target=self.startServer, args=[port])
      self.myThread.daemon = True
      self.myThread.start()

def startServer (self, port, username = None, password = None):
      try:
         port = int(port)

         # Multi Threaded
         self.httpd = ThreadedHTTPServer(('', port), AuthHandler)
         self.httpd.serve_forever()

      except Exception as e:
         self.logger.error (ext.getException(e))

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """Handle requests in a separate thread."""

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Wed Feb 14, 2018 8:55 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

Re: closing socket

I believe I am doing the same ..

the only issue I have is that the socket is not release immediately after shutdown & close

and don't understand why

socketServer.shutdown(socket.SHUT_RDWR)
complains about 2 args instead of 1 expected..

Karl

Posted on
Wed Feb 14, 2018 9:37 pm
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: closing socket

Here is how I close:

Code: Select all
   def stop (self):
      self.logger.debug ("Stopping HTTP server")
      self.httpd.shutdown
      #self.httpd.socket.close() # not really needed, causes Indigo headaches and not using it doesn't leave open sockets because the thread is destroyed
      self.httpd = None
      self.myThread.paused = True
      self.stopped = True

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Wed Feb 14, 2018 10:55 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

Re: closing socket

I believe
self.httpd.shutdown
should be
self.httpd.shutdown()

Posted on
Thu Feb 15, 2018 8:17 am
Colorado4Wheeler offline
User avatar
Posts: 2794
Joined: Jul 20, 2009
Location: Colorado

Re: closing socket

kw123 wrote:
I believe
self.httpd.shutdown
should be
self.httpd.shutdown()


Probably, but it's been working so I'm leaving it :lol:

My Modest Contributions to Indigo:

HomeKit Bridge | Device Extensions | Security Manager | LCD Creator | Room-O-Matic | Smart Dimmer | Scene Toggle | Powermiser | Homebridge Buddy

Check Them Out Here

Posted on
Thu Feb 15, 2018 8:33 am
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

Re: closing socket

Close()
Is the one that must be done.
Shutdown() sends to peer a message it’s over.
Close() will actually shut things down




Sent from my iPhone using Tapatalk

Posted on
Thu Feb 15, 2018 9:17 am
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: closing socket

I'm not sure of the semantics of doing it with ThreadedTCPServer, but when you create the listening socket set the socket option SO_REUSEADDR. Example:

Code: Select all
socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

Image

Posted on
Thu Feb 15, 2018 10:15 am
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

Re: closing socket

Thanks will try that.



Sent from my iPhone using Tapatalk

Posted on
Thu Feb 15, 2018 10:21 am
jay (support) offline
Site Admin
User avatar
Posts: 18199
Joined: Mar 19, 2008
Location: Austin, Texas

Re: closing socket

Also, set the socket timeout to something lower - it could be that it's waiting for something and just hasn't timed out yet. The default is 30 seconds (way too long for most things IMO).

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 4 guests