我正在尝试使用ws4py在CherryPy中动态创建/销毁“支持websocket”的路径。这是一个演示问题的完整程序:
import cherrypy
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import EchoWebSocket, WebSocket
class Nothing(object):
@cherrypy.expose
def index(self):
pass
class Root(object):
@cherrypy.expose
def index(self):
return "Tweep tweep!"
@cherrypy.expose
def add(self, bird):
# Try to create a new websocket-capable path.
cherrypy.tree.mount(Nothing(), "/bird/" + bird, config={"": {"tools.websocket.on": True, "tools.websocket.handler_cls": EchoWebSocket}})
@cherrypy.expose
def remove(self, bird):
# Remove a previously created websocket-capable path.
del cherrypy.tree.apps["/bird/" + bird]
@cherrypy.expose
def other(self):
pass
cherrypy.config.update({"server.socket_host": "localhost", "server.socket_port": 9000})
WebSocketPlugin(cherrypy.engine).subscribe()
cherrypy.tools.websocket = WebSocketTool()
cherrypy.quickstart(Root(), "/", config={"/other": {"tools.websocket.on": True,"tools.websocket.handler_cls": EchoWebSocket}})
这是我可以构造的一个简单示例:Root类作为主应用程序,以及ws4py config指令,以允许在ws://localhost:9000/other
创建websockets。 add()
方法创建一个新应用程序并将其安装在适当的路径上,以模仿“/ other”应用程序的设置。
启动服务器后,我可以在Chrome的JavaScript控制台中执行此操作:
> w = new WebSocket("ws://localhost:9000/other")
WebSocket {binaryType: "blob", extensions: "", protocol: "", onclose: null, onerror: null…}
> w.onmessage = function (d) { console.log(d.data); }
function (d) { console.log(d.data); }
> w.send("testing 1 2 3")
true
testing 1 2 3
太棒了,它有效!
现在,在浏览器中访问http://localhost:9000/add/eagle
之后(为了创建新路径),我在控制台中进行了以下交换:
> w = new WebSocket("ws://localhost:9000/bird/eagle")
WebSocket {binaryType: "blob", extensions: "", protocol: "", onclose: null, onerror: null…}
WebSocket connection to 'ws://localhost:9000/bird/eagle' failed: Unexpected response code: 301
嗯......为什么我会得到301?只是为了显示“/ bird / eagle”和我没有使用“添加”路径“创建”的其他路径之间的区别:
> w = new WebSocket("ws://localhost:9000/bird/pelican")
WebSocket {binaryType: "blob", extensions: "", protocol: "", onclose: null, onerror: null…}
WebSocket connection to 'ws://localhost:9000/bird/pelican' failed: Unexpected response code: 404
404有道理;服务器上没有这样的路径。但是为什么在安装专门用于此websocket创建目的的新应用程序后获得301?为什么它的行为与服务器启动时设置的不同(在路径“/ other”上)?我可以做些什么来完成我追求的这种行为?
答案 0 :(得分:1)
虽然我不明白为什么我会得到301,但我确实弄清楚如何以我想要的方式实现这项工作。诀窍似乎是我无法在处理程序对象的“索引”路径上安装websocket处理程序。相反,您需要在其他命名路径上执行此操作。我的示例程序只在两个地方改变了:
(1)“Nothing”类获得了一种新方法:
@cherrypy.expose
def ws(self):
pass
(2)安装动态创建的处理程序的行会更改其挂载点:
cherrypy.tree.mount(Nothing(), "/bird/" + bird, config={"/ws": {"tools.websocket.on": True, "tools.websocket.handler_cls": EchoWebSocket}})
现在事情很顺利。我可以在“add /”URL中添加一个鸟,然后从控制台实例化一个websocket对象并通过它进行通信,最后我可以在“remove /”URL中删除该鸟。
答案 1 :(得分:0)
当请求命中某个index()页面处理程序时,301是CherryPy的默认行为/如果它的处理程序是index(),那么/ bird会重定向到/ bird /。
您可以通过为定义索引的类禁用trailing_slah工具来禁用此行为。
tools.trailing_slash.on: False
这应该可以解决问题。