tornado how to use WebSockets with wsgi

只愿长相守 提交于 2021-01-28 23:32:26

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!