我正试图在openshift.com服务器上实现websocket(它应该支持它们)。
openshift.com为我提供了一个WSGI,因此我将cherrypy
嵌入其中,以便wsgi.py
脚本定义一个application
对象。此外,cherrypy
有一个由ws4py
定义的websocket工具。
这是一个在OpenShift中的WSGI下工作的最小cherrypy应用程序,也应该使用websockets!
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'
(我手动删除了文件名中的绝对路径)PS:我使用python3.3
、cherrypy==3.5.0
、ws4py==0.3.4
。
我不清楚:
- 如果这是在WSGI环境中cherrypy和ws4py之间缺乏兼容性
- 如果在WSGI环境中是ws4py的问题
- 如果是因为Openshift websocket的端口与http端口不同
PPS:这是一个完整的OpenShift项目,你可以自己运行并尝试:https://github.com/spocchio/wsgi-cherrypy-ws4py
我认为这根本不可能。WSGI是一个同步协议(1,2),WebSocket协议是异步的。Wiki指出,对于Python应用程序接口,OpenShift使用WSGI(3)。唉。
然而,我最近在pub/sub场景中使用了ws4py,它在CherryPy标准HTTP服务器部署之上运行得非常好。因此,在没有应用程序接口约束的通用虚拟服务器上,这应该不是问题。