Как использовать 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