2013-11-27 90 views
0

我試圖在同一個HTTP路由上提供HTTP-Answer和WebSocket。在同一路由上提供HTTP和WebSocket(播放框架2.1)

GET /       controllers.Application.index() 
    GET /       controllers.Application.ws() 

在早期版本的Play Framework中,可以爲「WS」定義路由,從而區分HTTP和WS請求。由於即時通訊使用2.1,我需要另一種可能性使HTTP和WS請求在同一個路由上工作。

因爲WebSocket和Result不是在同一個類型層次結構中,我不能將映射推遲到處理程序方法。 有沒有什麼方法可以根據HTTP或WS的請求重新路由請求?

在此先感謝!

回答

1

這可以通過編寫自己的路由器來實現 - 上述操作不適用於Plays路由器,因爲您希望將/路由到兩個不同的終端,默認的播放路由器看起來不像除了請求方法和URI之外。所以,如果你重寫Global.onRouteRequest看起來是這樣的:

override def onRouteRequest(req: RequestHeader): Option[Handler] = { 
    if (req.method == "GET" && req.path == "/" && 
     req.headers.get("Upgrade").exists(_.equalsIgnoreCase("websocket))) { 
    Some(controllers.Application.ws()) 
    } else { 
    super.onRouteRequest(req) 
    } 
} 

然後,從你的路由文件中刪除WebSocket的路線。

如果要爲Java做到這一點,它會是這個樣子:

public Handler onRouteRequest(play.api.mvc.RequestHeader req) { 
    if (req.method().equals("GET") && req.path().equals("/") && 
     req.headers().get("Upgrade").isDefined() && 
     req.headers().get("Upgrade").get().equalsIgnoreCase("websocket")) { 
    return play.core.j.JavaWebSocket.ofJson(new scala.Function0<WebSocket<JsonNode>>() { 
     public WebSocket<JsonNode> apply() { 
     return controllers.Application.ws(); 
     } 
    }); 
    } else { 
    return super.onRouteRequest(req); 
    } 
} 

不知道如果我有語法/類型100%正確的存在,但希望你能做出來。另外,請注意,如果您使用的是字符串或字節數組,則此處假定使用JSON WebSockets,然後使用JavaWebSocket.ofString/ofBytes。最後,請注意,這是一個內部API,可能隨時中斷。

+0

非常感謝您的回答 - 這對我有很大幫助! 現在我非常接近我的(乾淨的)解決方案,但留下了一個問題: Im現在在Java中,而「onRouterRequest(req)」 - 方法需要返回類型爲「Handler」的實例。由於「結果」或「WebSocket」不是處理程序,因此(controllers.Applications.ws())調用如何轉換爲處理程序的實例? – angrybobcat

+0

編輯我的迴應,包括Java解決方案。 –

+0

我編輯過,以改進Java代碼並確認它正在運行。我希望早些時候知道這件事。 –