2

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

4

2 に答える 2

0

301 は、リクエストが index() ページ ハンドラーにヒットしたときの CherryPy のデフォルトの動作です。

インデックスが定義されているクラスのtrailing_slahツールを無効にすることで、この動作を無効にすることができます。

tools.trailing_slash.on: False

これでうまくいくはずです。

于 2013-09-08T11:54:37.753 に答える