Как использовать TLS в Play! Framework WebSockets ( "wss://" )

Я не могу использовать wss:// в моем простом приложении WebSocket, созданном в Play! Framework 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");

и все работает отлично. Но если я изменяю ws:// на wss://, чтобы использовать TLS, он терпит неудачу, и я получаю следующее исключение Netty:

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

Как я могу сделать эту работу? Спасибо.

Ответ 1

Я действительно хотел понять это для вас! Но мне не понравился ответ. Похоже, что поддержка SSL для веб-сайтов отсутствует. Пила упоминает об этом здесь и никаких признаков прогресса с тех пор: 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:

Цель: конечная точка SSL WSS: forwards wss|https://ws.example.com to ws|http://ws1.example.com:10080

"Прокси-сервер также является конечной точкой SSL для соединений WSS и HTTPS. Таким образом, клиенты могут использовать соединения 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 настолько легкий и веселый. Не стесняйтесь пойти с этим вариантом.

Ответ 2

Вы пытались включить поддержку https на сервере воспроизведения? Похоже, вы пытаетесь подключиться к http-порту с помощью wss, который никогда не сможет работать, вам нужно включить https, а затем изменить URL-адрес не только на wss, но и использовать порт https.

Чтобы запустить сервер воспроизведения с включенным ssl:

activator run -Dhttps.port=9443

Затем подключитесь к wss://localhost:9443/ws2.

Ответ 3

Другим вариантом является использование SockJS в качестве уровня Websocket, реализация SockJS для Play2 может быть найдена в https://github.com/fdimuccio/play2-sockjs

Когда HTTPS включен, wss endpoind создается SockJS по каналу HTTPS. Play2-sockjs также поддерживает шаблон Actor, как с собственными веб-сайтами Play.

Если вы не хотите использовать SockJS в clientide, а скорее заставляете реализацию websocket браузера, вы можете использовать явную конечную точку websocket wss:////websocket