我不能在我用Play创建的简单WebSocket应用程序中使用wss://
!框架 2.2.它会回显消息。端点是这样的
def indexWS2 = WebSocket.using[String] {
request => {
println("got connection to indexWS2")
var channel: Option[Concurrent.Channel[String]] = None
val outEnumerator: Enumerator[String] = Concurrent.unicast(c => channel = Some(c))
// Log events to the console
val myIteratee: Iteratee[String, Unit] = Iteratee.foreach[String] {gotString => {
println("received: " + gotString)
// send string back
channel.foreach(_.push("echoing back "" + gotString + """))
}}
(myIteratee, outEnumerator)
}
}
并且路线描述为
GET /ws2 controllers.Application.indexWS2
我像这样从JS客户端创建一个连接
myWebSocket = new WebSocket("ws://localhost:9000/ws2");
一切正常。但是,如果我为了使用 TLS 而将ws://
更改为 wss://
,它会失败,并且出现以下 Netty 异常:
[error] p.nettyException - Exception caught in Netty
java.lang.IllegalArgumentException: empty text
我怎样才能做到这一点?谢谢。
我真的很想为你弄清楚这一点! 但我不喜欢这个答案。 似乎还没有对Websockets的SSL的Play支持。 在这里看到提到它,此后没有进展的迹象:http://grokbase.com/t/gg/play-framework/12cd53wst9/2-1-https-and-wss-secure-websocket-clarifications-and-documentation
但是,有希望! 您可以使用nginx作为安全Websocket(wss)端点,以转发到具有不安全Websocket端点的内部Play应用:
该页面 http://siriux.net/2013/06/nginx-and-websockets/提供了以下解释和 nginx 的示例代理配置:
目标:WSS SSL 终结点:forwards wss|https://ws.example.com to ws|http://ws1.example.com:10080
"代理也是WSS和HTTPS连接的SSL端点。因此,客户端可以使用 wss://连接(例如,来自通过HTTPS提供的页面),这些连接在损坏的代理服务器等情况下效果更好。
server {
listen 443;
server_name ws.example.com;
ssl on;
ssl_certificate ws.example.com.bundle.crt;
ssl_certificate_key ws.example.com.key;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
# like above
}
}
Nginx是如此轻巧和有趣。 会毫不犹豫地选择此选项。
您是否尝试在播放服务器上启用 https 支持? 看起来您正在尝试使用 wss 连接到 http 端口,这永远不起作用,您需要启用 https,然后不仅将 URL 更改为 wss,而且还要使用 https 端口。
要在启用 SSL 的情况下启动 Play 服务器,请执行以下操作:
activator run -Dhttps.port=9443
然后连接到wss://localhost:9443/ws2
。
wss
在Play 2.6中工作正常。
您可以通过路由获取 url,而不是对 websocket url 进行硬编码:
@import play.api.mvc.RequestHeader
@import controllers.routes
@()(implicit request: RequestHeader)
<!DOCTYPE html>
<html lang="en">
<head>
<title>...</title>
<script>
var wsUri = "@routes.MyController.indexWS2().webSocketURL(secure = true)";
var webSocket = new WebSocket(wsUri);
//...
</script>
</head>
<body>
...
</body>
</html>
另一种选择是使用 SockJS 作为 Websocket 层,Play2 的 SockJS 实现可以在https://github.com/fdimuccio/play2-sockjs
启用HTTPS后,SockJS通过HTTPS通道创建wss endpoind。Play2-sockjs 还支持 Actor 模式,就像原生 Play websockets 一样。
如果你不想在客户端使用 SockJS,而是强制浏览器 websocket 实现,你可以使用显式 websocket 端点 wss:////websocket