Python 3.x WSGI下cherrypy下的ws4py:exception AttributeError:';mod#wsgi.Input';对象没有属性';rfile';

Python 3.x WSGI下cherrypy下的ws4py:exception AttributeError:';mod#wsgi.Input';对象没有属性';rfile';,python-3.x,openshift,wsgi,cherrypy,ws4py,Python 3.x,Openshift,Wsgi,Cherrypy,Ws4py,我试图在openshift.com服务器上实现WebSocket(该服务器应该支持WebSocket) openshift.com为我提供了一个WSGI,因此我将我的cherrypy嵌入其中,以便我的WSGI.py脚本定义一个应用程序对象。 另外,cherrypy有一个websocket工具,由ws4py定义 这是一个最小的cherrypy应用程序,它在OpenShift的WSGI下工作,并且也应该使用WebSocket import cherrypy from ws4py.server.che

我试图在openshift.com服务器上实现WebSocket(该服务器应该支持WebSocket)

openshift.com为我提供了一个WSGI,因此我将我的
cherrypy
嵌入其中,以便我的
WSGI.py
脚本定义一个
应用程序
对象。 另外,
cherrypy
有一个websocket工具,由
ws4py
定义

这是一个最小的cherrypy应用程序,它在OpenShift的WSGI下工作,并且也应该使用WebSocket

import cherrypy
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import EchoWebSocket
import atexit
import logging

# see http://tools.cherrypy.org/wiki/ModWSGI
cherrypy.config.update({'environment': 'embedded'}) 
if cherrypy.__version__.startswith('3.0') and cherrypy.engine.state == 0:
    cherrypy.engine.start(blocking=False)
    atexit.register(cherrypy.engine.stop)

class Root(object):
    def index(self): return 'I work!'
    def ws(self): print('THIS IS NEVER PRINTED :(')
    index.exposed=True
    ws.exposed=True

# registering the websocket
conf={'/ws':{'tools.websocket.on': True,'tools.websocket.handler_cls': EchoWebSocket}}
WebSocketPlugin(cherrypy.engine).subscribe()
cherrypy.tools.websocket = WebSocketTool()  

#show stacktraces in console (for some reason this is not default in cherrypy+WSGI)
logger = logging.getLogger()
logger.setLevel(logging.INFO)
stream = logging.StreamHandler()
stream.setLevel(logging.INFO)
logger.addHandler(stream)

application = cherrypy.Application(Root(), script_name='', config=conf)
除了我创建一个websocket(连接到
ws://myserver:8000/ws
)时,其他一切都运行得非常好,这是我得到的堆栈跟踪:

 cherrypy/_cplogging.py, 214, HTTP Traceback (most recent call last):
   File "cherrypy/_cprequest.py", line 661, in respond
     self.hooks.run('before_request_body')
   File "cherrypy/_cprequest.py", line 114, in run
     raise exc
   File "cherrypy/_cprequest.py", line 104, in run
     hook()
   File "cherrypy/_cprequest.py", line 63, in __call__
     return self.callback(**self.kwargs)
   File "ws4py/server/cherrypyserver.py", line 200, in upgrade
     ws_conn = get_connection(request.rfile.rfile)
AttributeError: 'mod_wsgi.Input' object has no attribute 'rfile'
(我手动从文件名中删除了绝对路径) 注:我使用了python3.3、cherrypy==3.5.0、ws4py==0.3.4

我不清楚:

  • 如果这是因为在WSGI环境中cherrypy和ws4py之间缺乏兼容性
  • 如果在WSGI环境中出现ws4py问题
  • 如果是因为Openshift websockets的端口与http端口不同

PPS:这是一个完整的OpenShift项目,您可以自己运行并尝试:

我认为这根本不可能。WSGI是一个同步协议(,),WebSocket协议是异步的。Wiki声明,对于Python应用程序接口,OpenShift使用WSGI()。唉


不过,我最近在pub/sub场景中使用了ws4py,它在CherryPy标准HTTP服务器部署上运行得非常好。因此,在没有应用程序接口约束的通用虚拟服务器上,这应该不是一个问题。

我知道,在Heroku上,它工作得非常完美。不幸的是,WebSocket上有55秒的超时时间,因此客户端必须至少每分钟保持连接一次(这不是在后台运行的移动应用程序的最佳选择)。尽管WSGI规范在技术上不允许这样做,但问题更多地与正在使用的WSGI服务器有关。WebSocket代码依赖于在作为纯Python WSGI服务器实现的WSGI服务器上使用,该服务器直接处理客户端套接字本身。然后,它绕过WSGI规范和WSGI服务器,向下接触以获取客户端的实际套接字连接,并直接通过它进行通信。换句话说,它使用的是邪恶的黑客。这种攻击在mod_wsgi上不起作用,因为它不公开原始套接字连接。为了更清楚,我将在Python的情况下添加它,因此mod_wsgi for wsgi。格雷厄姆称之为“邪恶的黑客”的是,我确实不得不进行这样的黑客行为,对此我并不感到骄傲。不幸的是,WSGI规范是早在WebSocket之前编写的,并没有考虑用例。希望有一天它会被修改以解决这个问题。