2014-01-24 3 views
5

Я бегу приложение WebSocket на CloudBees - и я периодически вижу:перемежающейся Ошибка при WebSocket рукопожатия: Неожиданный код ответа: 400 на CloudBees

Error during WebSocket handshake: Unexpected response code: 400 

Я сказал это, чтобы использовать HTTP 1.1, чтобы Апгрейды с помощью:

bees app:proxy:update http_version=1.1 

И он работает, но иногда я вижу ошибку (не всегда).

ответ

20

Это почти наверняка связано с тем, что не используется https (SSL). Websocket поверх простого http уязвим для прокси в середине (часто прозрачный), работающий на уровне http, нарушающем соединение.

Это обычное явление в сотовых сетях или в офисных сетях, которые могут использовать несколько беспроводных соединений с прокси-сервером, который распространяет HTTP-запросы через соединения.

Единственный способ избежать этого - использовать SSL все время - это дает websocket лучший шанс работать.

1

Добавление к решению Майкла Нила.

Как указано there, игра не поддерживает WSS изначально, по состоянию на конец октября 2013 г.

Так просто переход на SSL не будет работать.

К счастью, при настройке приложения на использование SSL Cloudbees устанавливает сервер Nginx в качестве маршрутизатора, при этом конечная точка SSL является маршрутизатором, поэтому обходной путь, описанный there, будет работать.

Итак, создав собственное доменное имя и соответствующий псевдоним приложения Cloudbees, настройте свои SSL-сертификаты на маршрутизаторе Cloudbees и настройте приложение для использования этого маршрутизатора Cloudbees, вы сможете подключиться к веб-сайтам ,

Но вам придется принудительно защищать URL-адреса, поскольку использование обычных игровых автоматов невозможен. Они возвращают ws: // ..., а не wss: // ... URL-адреса веб-сайтов.

В частности, с использованием вне коробки Play Framework sample Scala Websocket Chat app в качестве примера:

  1. Conf/маршрутов определяет:

    GET /room/chat controllers.Application.chat(username) 
    
  2. Применение определяет:

    def chat(username: String) = WebSocket.async[JsValue] { request => ChatRoom.join(username) } 
    
  3. и chatRoom.scala.js создает веб-сокет:

    var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket 
    var chatSocket = new WS("@routes.Application.chat(username).webSocketURL()") 
    

Это не будет работать, так как @routes .... webSocketURL() будет возвращать WS: //, а не WSS: // URL.

chatRoom.scala.JS может быть изменен следующим образом, чтобы заставить его работать независимо от того, является ли он работает в пределах https: // или HTTP: // страница:

var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket; 
var wsUrl = "@controllers.api.routes.PubSubController.chat(username).webSocketURL()"; 
if(window.location.protocol == "https:") wsUrl = wsUrl.replace("ws:","wss:"); 
var chatSocket = new WS(wsUrl); 

Надеется, что это помогает.

+0

должен не X-Forwarded-Прото сказать играть, что соединение было безопасным - и использовать WSS при написании URL-адресов? если это не так - это ошибка игры, я думаю. –

1

Если это прерывисто, возможно, что ваша клиентская библиотека имеет некоторые проблемы с созданием действительного рукопожатия через некоторое время. Было бы полезно запустить Wireshark для захвата HTTP-запросов, содержащих заголовки Connection: Upgrade, чтобы подтвердить, что запрос подтверждения приветствия.

Для способов, как это могло произойти, см subsection 4.2.1 of the WebSockets RFC 6455: заголовок

The client's opening handshake consists of the following parts. If 
    the server, while reading the handshake, finds that the client did 
    not send a handshake that matches the description below (note that as 
    per [RFC2616], the order of the header fields is not important), 
    including but not limited to any violations of the ABNF grammar 
    specified for the components of the handshake, the server MUST stop 
    processing the client's handshake and return an HTTP response with an 
    appropriate error code (such as 400 Bad Request). 
+0

Это вполне может быть - конкретный случай, который вызвал это, был кто-то в удаленном офисе, который выполнял более двух сотовых соединений - с некоторым прокси-сервером, который бы балансировал между ними. В любом случае, SSL был в работе, поэтому он может помочь в этом. Я считаю, что в этом случае это был хром - никакой библиотеки за пределами используемой. –

+2

Развернув несколько общедоступных приложений с использованием WebSockets, требуется wss: //, особенно для крупных сетей сотовых операторов в США. Сети AT & T, Verizon, T-Mobile могут не иметь посредников, поддерживающих WebSocket, для каждого маршрута. Chrome, похоже, очень хорошо реализовал спецификацию WebSocket, поэтому я бы наверняка опирался на эти сетевые проблемы. – nowucca

Смежные вопросы