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
. この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」上) とは異なる動作をするのはなぜですか? そして、私が求めているこの行動を達成するために、私は何を別の方法で行うことができますか?