2013-08-30 36 views
1

我想在CherryPy中使用ws4py動態創建/銷燬「websocket-capable」路徑。下面是一個說明該問題的完整方案:如何添加websocket路徑到正在運行的CherryPy應用程序?

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}}) 

這很簡單,只要我可以構建一個例子:根類被作爲主要的應用,具有ws4py配置指令一起允許創建的WebSockets的在ws://localhost:9000/otheradd()方法創建一個新的應用程序並將其安裝在適當的路徑上,以模擬「/ 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?只是爲了顯示「/只/鷹」和其他一些路徑,我沒有「創造」使用「添加」路徑之間的區別:

> 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

一些注意事項:如果在'其他()'方法,我喜歡的東西'回報更換'pass'聲明「確定」',我不能在我的第一個JS控制檯例如創建類似的WebSockets 。而不是301或404,我得到一個「意想不到的200」。這種說法是有道理的,因爲在這種情況下服務器被設置爲返回一個有效的結果,我猜想它會干擾websocket協議。這就是爲什麼我將'Nothing'類作爲動態安裝應用程序的根對象。 –

回答

1

雖然我不明白爲什麼我得到的是301,我也沒搞清楚,如何真正使這項工作我想它的方式。技巧似乎是我無法在處理程序對象的「索引」路徑上安裝websocket處理程序。相反,你需要在其他命名路徑上完成它。我的示例程序,在短短兩個地方改變:

(1)中的「無」類獲得了新的方法:

@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處刪除鳥。

0

301 CherryPy的是一個默認的行爲,當一個請求命中索引()頁面處理器確實/所以/鳥會重定向到/只/如果它的處理器是指數()。

您可以通過爲定義索引的類禁用trailing_slah工具來禁用此行爲。

tools.trailing_slash.on: False 

這應該是訣竅。

+0

Sylvain,感謝您提供這方面的信息。我甚至沒有想到斜槓工具可能是問題所在。當我有機會時,我會試試這個。 –

+0

嗨Sylvain。長時間更新,我知道:)。不幸的是,打開trailing_slash工具沒有幫助。如果可能的話,我想擺脫我的websocket路徑上尾隨的''/ ws''。你還有其他建議嗎? –

相關問題