【问题标题】:tornado how to use WebSockets with wsgitornado 如何在 wsgi 中使用 WebSockets
【发布时间】:2016-11-06 08:43:41
【问题描述】:

我正在尝试使用 python 制作一个游戏服务器,使用 tornado。

问题在于 WebSockets 似乎不适用于 wsgi。

wsgi_app = tornado.wsgi.WSGIAdapter(app)
server = wsgiref.simple_server.make_server('', 5000, wsgi_app)
server.serve_forever()

在查看 stackoverflow 上的这个答案后,Running Tornado in apache,我更新了我的代码以使用 HTTPServer,它适用于 websockets。

server = tornado.httpserver.HTTPServer(app)
server.listen(5000)
tornado.ioloop.IOLoop.instance().start()

但是,当我使用 HTTPServer 时,出现错误:TypeError: __call__() takes exactly 2 arguments (3 given)

在互联网上查找此问题,我在这里找到了问题的答案: tornado.wsgi.WSGIApplication issue: __call__ takes exactly 3 arguments (2 given)

但在app周围添加tornado.wsgi.WSGIContainer后,错误仍然存​​在。

我该如何解决这个问题?或者有什么方法可以在 wsgi 中使用 tornado web sockets。

这是我目前的代码:

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()

提前致谢!非常感谢您的帮助。

【问题讨论】:

    标签: python python-2.7 tornado wsgi


    【解决方案1】:

    HTTPServer 需要tornado.web.Application,这与 WSGI 应用程序不同(可以与WSGIContainer 一起使用)。

    如果您需要 WSGI 和 websockets,建议您在两个单独的进程中运行它们,并在它们之间选择一个 IPC 机制(并使用真正的 WSGI 服务器而不是 Tornado 的WSGIContainer)。如果您需要在同一过程中执行它们,您可以使用FallbackHandler

    wsgi_container = tornado.wsgi.WSGIContainer(my_wsgi_app)
    application = tornado.web.Application([
        (r"/ws", MyWebSocketHandler),
        (r".*", FallbackHandler, dict(fallback=wsgi_container),
    ])
    

    【讨论】:

    • 什么是my_wsgi_app
    • 这就是您正在构建的应用程序,是您使用的任何 WSGI 框架的结果。您在上面粘贴的应用程序是纯 Tornado;如果这就是您的应用程序的样子,则无需涉及任何与 WSGI 相关的内容。只有在使用 Flask 等基于 WSGI 的框架时才需要 WSGI。
    • 啊,我明白了!谢谢你。我会尽快尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    相关资源
    最近更新 更多