Close port using Tornado web server - python

I am running a Tornado web server to send GET and POST requests. I want to be able to shut it down to do modifications on it and start it when finished to test it. But I cant, the port used is in used forever...
def startTornado():
application = tornado.web.Application([
(r"/", MainHandler),
])
application.listen(80)
tornado.ioloop.IOLoop.instance().start()
print "Server is running"
def stopTornado():
ioloop = tornado.ioloop.IOLoop.instance()
ioloop.add_callback(ioloop.stop)
print "Asked Tornado to exit"
if __name__ == "__main__":
#stopTornado()
startTornado()
I checked all the answer on the web, but I it doesnt help me.
ioloop = tornado.ioloop.IOLoop.instance()
ioloop.add_callback(ioloop.stop)
Doesnt close the port. It is still in use :
TCP 0.0.0.0:80 PC-1:0 LISTENING
[python.exe]
Does anyone have an idea ?

To close the port, you must call HTTPServer.close(), not IOLoop.stop() (a stopped IOLoop can be restarted). This means using
server = HTTPServer(application)
server.listen(80)
instead of the Application.listen convenience method.

Related

How to write a Tornado listener correctly?

I wanted to write a server background listener to listen to dozens of clients sending commands to this background listener on TCP port 8888. Command format is "http://myip/?c="ClientCommand=A5"
Those clients could be sending commands at the same time or different time. Also, these clients will stay connected and sending few different commands until disconnect by client themselves. All the commands received by the background listener will be written to a MySQL DB.
After few days of study, I found Python + Tornado framework could be a good tool to do this. However, I have tried few days with examples from the web and I still don't know how to program this background listener.
Here is an example I found on a blog and it worked...How do I modify the code below to do the background listener? I know I need to use GET to get parameters from the URL. I have tried get(self.get), but I got error of invalid syntax...
Thanks for your help.
import tornado.ioloop
import tornado.web
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, Tornado!")
if __name__ == "__main__":
application = tornado.web.Application([
(r"/", IndexHandler)
])
application.listen(8888)
tornado.ioloop.IOLoop.current().start()

How to receive dbus signals when there is a webserver running forever?

Hey guys I was planning to make my webserver works with dbus signal receiving. The webserver runs with gevent.WSGIServer because I need the support of websocket, while the dbus is handled via python-dbus package.
The question is:
webserver always has an event loop running forever, however to
receive dbus signals, python-dbus requires another event loop (which
is mainloop) to run forever as well.
I am not able to make the webserver running while keeping snooping
to dbus signals.
Here are my codes:
if __name__ == '__main__':
log = logging.getLogger('Rocket.Errors')
log.setLevel(logging.INFO)
log.addHandler(logging.StreamHandler(sys.stdout))
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
app = Bottle()
# Register the dbus recieve handler
#bus.add_signal_receiver(hostHeartBeatSignal)
bus.add_signal_receiver(testSignal)
**This will block the webserver from running!!!!!!!!**
mainloop = gobject.MainLoop()
mainloop.run()
#app.route('/websocket', skip = True)
def handle_websocket():
print "Entering websocket handling"
wsock = request.environ.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
while True:
try:
message = wsock.receive()
print "Message received"
wsock.send("Your message was: %r" % message)
print "Message sent"
except WebSocketError:
break
default_cert = os.path.join(sys.prefix, 'share',
os.path.basename(__file__), 'cert.pem')
from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketError
from geventwebsocket.handler import WebSocketHandler
server = WSGIServer(("0.0.0.0", 443), app, keyfile = default_cert,
certfile = default_cert,
handler_class=WebSocketHandler)
server.serve_forever()
You can run one of those main loops in another thread.

Error when running tornado Webserver in terminal

I am trying to run a tornado webserver in the terminal, but when I run it I simply get a space which is completely empty, and then I have no way of closing the server. Right now I am trying the hello world example.
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Any help would be much appreciated. I have already taken a look at the getting Tornado working question, and the answers there did not solve the issue.
All you need to do is type this URL in your browser
http://127.0.0.1:8888
But if you do see any error messages
Try changing your port.May be it is being used by other program
application.listen(7777)
Now point your browser to
http://127.0.0.1:7777
Stopping the server
A simple ctrl+c would kill the process.But if you want to do more cleaner way
try:
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
tornado.ioloop.IOLoop.instance().stop()

Stopping a tornado application

Let's take the hello world application in the Tornado home page:
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Is there a way, after the IOloop has been started and without stopping it, to essentially stop the application and start another one (on the same port or on another)?
I saw that I can add new application (listening on different ports) at runtime, but I do not know how I could stop existing ones.
Application.listen() method actually creates a HTTPServer and calls its listen() medthod. HTTPServer objects has stop() method which is probably what you need. But in order to do it you have to explicitly create HTTPServer object in your script.
server = HTTPServer(application)
server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
#somewhere in your code
server.stop()
Here is a gist about how to gracefully and safely shutdown the tornado ioloop.
https://gist.github.com/nicky-zs/6304878
However, you can refer to this implementation to achieve your goal.
To add to #Alex Shkop's answer a few years later, as of Tornado 4.3 .listen() returns a reference to its HTTPServer!
https://www.tornadoweb.org/en/stable/web.html#tornado.web.Application.listen
server = app.listen()
... # later
server.stop()
Further, if you're working in a Jupyter notebook and for some reason need a Tornado server, you can try to close the HTTPServer before you recreate it to avoid OSError: [Errno 98] Address already in use on re-running the cell
# some Jupyter cell
#
import tornado.web
try:
server.stop() # NameError on first cell run
except Exception as ex:
print(f"server not started to stop: {repr(ex)}")
else: # did not raise NameError: server was running
print(f"successfully stopped server: {server}")
app = tornado.web.Application(...)
server = app.listen(9006) # arbitrary listening port

Python : How do server come to know of network failure at the client side?

I am developing a chat based application in Python using twisted module.
After a period of establishing the connection, let us assume, that the network connection fails at the client side.
How do I make sure that the server is notified about the network failure ?
Here is the code snippet( Server program) :
def main():
"""This runs the protocol on port 8000"""
factory = protocol.ServerFactory()
factory.protocol = Echo
PortNo = 8000
reactor.listenTCP(PortNo,factory)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
Thanks
This http://twistedmatrix.com/documents/13.0.0/api/twisted.internet.interfaces.IProtocol.html#connectionLost
But to be realy sure, you'd have to implement PING/PONG in the application. See https://www.rfc-editor.org/rfc/rfc2812#section-3.7.2
You have to (1) use a read timeout and (2) make sure you react appropriately to all error conditions when reading from or writing to the socket.

Categories

Resources