我正在尝试使用 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 配置指令以允许在ws://localhost:9000/other
. 该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”和我没有使用“add”路径“创建”的其他路径之间的区别:
> 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”上)?为了实现我所追求的这种行为,我可以做些什么不同的事情?