问题
I am trying to make a game server with python, using tornado.
The problem is that WebSockets don't seem to work with wsgi.
wsgi_app = tornado.wsgi.WSGIAdapter(app)
server = wsgiref.simple_server.make_server('', 5000, wsgi_app)
server.serve_forever()
After looking trough this answer on stackoverflow, Running Tornado in apache, I've updated my code to use a HTTPServer
, which works with websockets.
server = tornado.httpserver.HTTPServer(app)
server.listen(5000)
tornado.ioloop.IOLoop.instance().start()
However when I use the HTTPServer, an error comes up saying: TypeError: __call__() takes exactly 2 arguments (3 given)
Looking this up on the internet, I found an answer to the question here: tornado.wsgi.WSGIApplication issue: __call__ takes exactly 3 arguments (2 given)
But after adding tornado.wsgi.WSGIContainer
around app
, the error persists.
How can I solve this problem? Or is there any way to use tornado web sockets with wsgi.
Here is my code at the moment:
import tornado.web
import tornado.websocket
import tornado.wsgi
import tornado.template
import tornado.httpserver
#import wsgiref.simple_server
import wsgiref
print "setting up environment..."
class TornadoApp(tornado.web.Application):
def __init__(self):
handlers = [
(r"/chat", ChatPageHandler),
(r"/wschat", ChatWSHandler),
(r"/*", MainHandler)
]
settings = {
"debug" : True,
"template_path" : "templates",
"static_path" : "static"
}
tornado.web.Application.__init__(self, handlers, **settings)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("test.html", food = "pizza")
class ChatPageHandler(tornado.web.RequestHandler):
def get(self):
self.render("chat.html")
class ChatWSHandler(tornado.websocket.WebSocketHandler):
connections = []
def open(self, *args):
print 'a'
self.connections.append(self)
print 'b'
self.write_message(u"@server: WebSocket opened!")
print 'c'
def on_message(self, message):
[con.write_message(u""+message) for con in self.connections]
def on_close(self):
self.connections.remove(self)
print "done"
if __name__ == "__main__":
app = TornadoApp()
server = tornado.httpserver.HTTPServer(tornado.wsgi.WSGIContainer(app))
server.listen(5000)
tornado.ioloop.IOLoop.instance().start()
Thank's in advace! Help much appreciated.
回答1:
HTTPServer
needs a tornado.web.Application
, which is not the same as a WSGI application (which you could use with WSGIContainer
).
It is recommended that if you need both WSGI and websockets that you run them in two separate processes with an IPC mechanism of your choice between them (and use a real WSGI server instead of Tornado's WSGIContainer
). If you need to do them in the same process, you can use a FallbackHandler.
wsgi_container = tornado.wsgi.WSGIContainer(my_wsgi_app)
application = tornado.web.Application([
(r"/ws", MyWebSocketHandler),
(r".*", FallbackHandler, dict(fallback=wsgi_container),
])
来源:https://stackoverflow.com/questions/38187728/tornado-how-to-use-websockets-with-wsgi