WebSocket握手期间的间歇性错误:CloudBees上的意外响应代码:400

时间:2014-01-24 23:29:58

标签: websocket cloudbees

我在CloudBees上运行一个websocket应用程序 - 我间歇地看到:

Error during WebSocket handshake: Unexpected response code: 400

我告诉它使用http 1.1允许通过以下方式升级:

bees app:proxy:update http_version=1.1

它有效,但我有时会看到错误(并非总是如此)。

3 个答案:

答案 0 :(得分:20)

这几乎可以肯定是因为没有使用https(SSL)。普通http上的Websocket容易受到中间(通常是透明的)操作在http层破坏连接的代理的攻击。

这在蜂窝网络或办公室网络上很常见,这些网络或办公室网络可能使用多个无线连接,代理可以跨连接传播http请求。

避免这种情况的唯一方法是始终使用SSL - 这为websocket提供了最佳的工作机会。

答案 1 :(得分:1)

添加迈克尔尼尔的解决方案。

如上所述there,Play自2013年10月下旬以来一直不支持WSS。

因此,简单地切换到SSL是行不通的。

值得庆幸的是,在配置应用程序以使用SSL时,Cloudbees将Nginx服务器设置为路由器,SSL端点为路由器,因此描述there的解决方法将起作用。

因此,一旦您创建了自定义域名和相应的Cloudbees应用程序别名,在Cloudbees路由器中设置您的SSL证书,并将您的应用配置为使用该Cloudbees路由器,您就可以连接到websockets。

您必须强制网址安全,因为使用常规Play路线解析器无法使用。他们返回ws:// ...,而不是wss:// ... websockets URL。

具体来说,使用开箱即用的Play Framework sample Scala Websocket Chat app作为示例:

  1. conf / routes定义:

    GET /room/chat controllers.Application.chat(username)
    
  2. 应用程序定义:

    def chat(username: String) = WebSocket.async[JsValue] { request => ChatRoom.join(username) }
    
  3. 并且chatRoom.scala.js创建了Web套接字:

    var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket 
    var chatSocket = new WS("@routes.Application.chat(username).webSocketURL()") 
    
  4. 这不起作用,因为@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);
    

    希望这有帮助。

答案 2 :(得分:1)

如果是间歇性的,可能是您的客户端库在一段时间后形成有效的握手有些麻烦。运行Wireshark以捕获包含Connection:Upgrade标头的HTTP请求以验证握手请求是否有效是有用的。

有关如何实现这种情况的方法,请参阅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).