11

我无法wss://在使用 Play!Framework 2.2 创建的简单 WebSocket 应用程序中使用。它回显了消息。端点是这样的

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");

一切正常。但是,如果我更改ws://wss://使用 TLS,它会失败并且我得到以下 Netty 异常:

[error] p.nettyException - Exception caught in Netty
java.lang.IllegalArgumentException: empty text

我怎样才能使这项工作?谢谢。

4

4 回答 4

11

我真的很想为你解决这个问题!但我不喜欢这个答案。似乎还没有针对 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 端点的内部播放应用程序:

页面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 是如此的轻巧和有趣。会毫不犹豫地选择这个选项。

于 2013-10-25T17:54:57.997 回答
7

您是否尝试在 Play 服务器上启用 https 支持?看起来您正在尝试使用 wss 连接到 http 端口,但这永远无法正常工作,您需要启用 https,然后不仅将 URL 更改为 wss,而且还要使用 https 端口。

在 ssl 开启的情况下启动 Play 服务器:

activator run -Dhttps.port=9443

然后连接到wss://localhost:9443/ws2.

于 2014-12-19T00:33:28.957 回答
2

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>
于 2018-04-10T09:55:19.997 回答
0

另一种选择是使用 SockJS 作为 Websocket 层,Play2 的 SockJS 实现可以在 https://github.com/fdimuccio/play2-sockjs找到

启用 HTTPS 后,SockJS 通过 HTTPS 通道创建一个 wss 端点。Play2-sockjs 也支持 Actor 模式,就像原生 Play websockets 一样。

如果您不想在客户端使用 SockJS 而是强制浏览器 websocket 实现,则可以使用显式 websocket 端点 wss:////websocket

于 2014-11-09T05:05:45.243 回答