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

WebSocket握手期间出现间歇性错误:CloudBees上的意外响应代码:400,websocket,cloudbees,Websocket,Cloudbees,我正在CloudBees上运行一个websocket应用程序-我偶尔会看到: Error during WebSocket handshake: Unexpected response code: 400 我已经告诉它使用http 1.1允许通过以下方式进行升级: bees app:proxy:update http_version=1.1 这是可行的,但我有时会看到错误(并非总是如此) 这几乎可以肯定是由于没有使用https(SSL)。在纯HTTP上,WebSoCube容易受到中间层(通常

我正在CloudBees上运行一个websocket应用程序-我偶尔会看到:

Error during WebSocket handshake: Unexpected response code: 400
我已经告诉它使用http 1.1允许通过以下方式进行升级:

bees app:proxy:update http_version=1.1

这是可行的,但我有时会看到错误(并非总是如此)

这几乎可以肯定是由于没有使用https(SSL)。在纯HTTP上,WebSoCube容易受到中间层(通常是透明的)代理的破坏,HTTP层破坏了连接。p> 这在蜂窝网络或办公网络上很常见,这些网络可能使用多个无线连接,并通过代理将http请求分散到多个连接上


避免这种情况的唯一方法是一直使用SSL——这给了websocket最好的工作机会

添加到Michael Neale的解决方案中

如上所述,截至2013年10月底,Play不支持WSS本机

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

谢天谢地,当配置应用程序使用SSL时,Cloudbees将Nginx服务器设置为路由器,SSL端点就是路由器,因此所描述的解决方法将起作用

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

但是您必须强制URL是安全的,因为使用常规的播放路由解析程序将不起作用。它们返回ws://…,而不是wss://... websockets URL

具体来说,以开箱即用为例:

  • conf/routes定义:

    GET /room/chat controllers.Application.chat(username)
    
    def chat(username: String) = WebSocket.async[JsValue] { request => ChatRoom.join(username) }
    
  • 应用程序定义:

    GET /room/chat controllers.Application.chat(username)
    
    def chat(username: String) = WebSocket.async[JsValue] { request => ChatRoom.join(username) }
    
  • 然后chatRoom.scala.js创建web套接字:

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

    希望这有帮助。

    如果是间歇性的,可能是您的客户端库在一段时间后形成有效握手时遇到了一些问题。运行Wireshark捕获包含Connection:Upgrade标头的HTTP请求,以验证握手请求是否有效,这将是一种有益的做法

    有关如何实现这一点的方法,请参阅


    这很可能是一个特定的案例,促使这是一个在远程办公室的人,碰巧运行了2个手机连接,有一些代理可以在它们之间取得平衡。不管怎么说,SSL正在进行中,因此它可以帮助解决这个问题。我相信在这种情况下是chrome的——除此之外没有其他库。在部署了一些使用WebSocket的公共应用程序之后,wss://是一项要求,特别是对于美国的主要蜂窝运营商网络。AT&T、Verizon、T-Mobile网络可能没有每一条路由都有WebSocket握手感知中介。Chrome似乎已经很好地实现了WebSocket规范,所以我肯定会倾向于这些网络问题。X-Forwarded-Proto头不应该告诉play连接是安全的吗?并且在编写URL时使用wss吗?如果没有,我想这是一个游戏迷。