龙卷风如何在 wsgi 中使用 WebSockets [英] tornado how to use WebSockets with wsgi

查看:28
本文介绍了龙卷风如何在 wsgi 中使用 WebSockets的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to make a game server with python, using tornado.

问题是 WebSockets 似乎不适用于 wsgi.

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

在 stackoverflow 上查看这个答案后,在 apache 中运行 Tornado,我更新了我的代码使用 HTTPServer,它与 websockets 一起工作.

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

但是,当我使用 HTTPServer 时,会出现一个错误:TypeError: __call__() 需要 2 个参数(给出 3 个)

However when I use the HTTPServer, an error comes up saying: TypeError: __call__() takes exactly 2 arguments (3 given)

在网上查了一下,我在这里找到了这个问题的答案:tornado.wsgi.WSGIApplication 问题:__call__ 需要3 个参数(给出 2 个)

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)

但是在app周围添加tornado.wsgi.WSGIContainer后,错误依旧.

But after adding tornado.wsgi.WSGIContainer around app, the error persists.

我该如何解决这个问题?或者有什么方法可以通过 wsgi 使用 Tornado Web 套接字.

How can I solve this problem? Or is there any way to use tornado web sockets with wsgi.

这是我目前的代码:

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.

推荐答案

HTTPServer 需要一个 tornado.web.Application,它与 WSGI 应用程序不同(您可以将其与 WSGIContainer 一起使用).

HTTPServer needs a tornado.web.Application, which is not the same as a WSGI application (which you could use with WSGIContainer).

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

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),
])

这篇关于龙卷风如何在 wsgi 中使用 WebSockets的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆