龙卷风如何在 wsgi 中使用 WebSockets [英] tornado how to use WebSockets with wsgi
问题描述
我正在尝试使用 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屋!