WebSocket连接到' wss://mydomain.com:3001 /'失败:连接建立错误:net :: ERR_CONNECTION_CLOSED

时间:2015-12-04 05:59:28

标签: javascript ruby-on-rails ruby

em-websocket configration in rails 2.3.18 and ruby​​ 0.9.2

该应用程序托管在https:& http:sebsocket正在进行登台(http://)域,但是当我们将其转移到https://时,websocket会在同一时间后自动关闭。并在webconsole中遇到以下错误

WebSocket connection to 'wss://my_domain.com:3001/' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED

websocket.ym

 production:
   host: '0.0.0.0'
   port: 3001
   secure: true
   tls_options:
     private_key_file: filename.com.key
     cert_chain_file: filename.com.crt

的WebSockets应用内/ app.rb

em-websocet配置文件位置

" application_directory / WebSockets的应用内/ app.rb"它包含以下配置

require 'thin'
require 'em-websocket'
require 'yaml'
require 'active_support/core_ext/hash'

env          = ENV['WS_ENV'] || :development
logfile      = File.open('../log/websocket.log', 'a')
logfile.sync = true
WS_LOGGER    = Logger.new(logfile)
CONFIG       = YAML.load_file('../config/websocket.yml').with_indifferent_access[env]
EM.run do
    WS_LOGGER.info("Starting WebSockets server on port #{CONFIG[:port]}")
    @channel = EM::Channel.new
    WS_LOGGER.info("ENV:- #{env}")
    WS_LOGGER.info("CHANNEL:-----+#{@channel.inspect}")
  #EM::WebSocket.start(:host => '0.0.0.0', :port => '3001') do |ws|
  EM::WebSocket.start(CONFIG) do |ws|
    WS_LOGGER.info("Socket started----")
    WS_LOGGER.info("Socket inspect#{ws.inspect}")

    ws.onopen do |handshake|
    WS_LOGGER.info("HANDSHAKE:---WS open now!!")
    WS_LOGGER.info("handshake.secure? ..... #{handshake.secure?}")
      sid = @channel.subscribe { |msg| ws.send msg }
    WS_LOGGER.info("<#{sid}> WebSocket connection open")

      ws.onclose do
    @channel.unsubscribe(sid)
    WS_LOGGER.info("<#{sid}> Connection closed")
      end

      ws.onmessage do |msg|
    @channel.push msg
    WS_LOGGER.info("<#{sid}> Received Message: #{msg}")
      end
   end
  end
end

以生产模式启动websocket

WS_ENV=production bundle exec thin start -R app.rb &

检查日志

Starting WebSockets server on port 3001
I, [2015-12-03T20:50:25.588306 #4861]  INFO -- : ENV:- production
I, [2015-12-03T20:50:25.588341 #4861]  INFO -- : CHANNEL:-----+#   <EventMachine::Channel:0x315e908 @uid=0, @subs={}>
I, [2015-12-03T20:50:53.723973 #4861]  INFO -- : Socket started----
I, [2015-12-03T20:50:53.724169 #4861]  INFO -- : Socket inspect#<EventMachine::WebSocket::Connection:0x315dee0 @secure=true, @tls_options=
{"private_key_file"=>"filename.com.key", "cert_chain_file"=>"filename.com.crt"}, @debug=false, @signature=4, @close_timeout=nil, @handler=nil, @secure_proxy=false, @options=   {"port"=>3001, "secure"=>true, "tls_options"=>{"private_key_file"=>"filename.com.key", "cert_chain_file"=>"filename.com.crt"}, "host"=>"0.0.0.0"}>

在Javascript ###

中创建webSocket实例
host = "wss://mydomain.com:3001"; socket = new WebSocket(host);

1 个答案:

答案 0 :(得分:0)

为什么使用SSL / TLS 失败(将其留给代理)

大多数代理和生产应用程序&#34;包装&#34; (即Heroku Dynos)在将任何SSL数据转发给处理应用程序之前对其进行解密。

,即当使用nginx作为SSL连接的代理时,证书和加密通常由nginx 管理,数据以明文的形式发送到本地应用程序。

您的问题的答案应该是为您的应用使用明文,并让本地代理处理SSL / TLS加密。

证明我的观点:

由于我不喜欢em-websocket(我偏向自己的宠物项目),这里有一个快速Plezi应用程序,有或没有自签名SSL证书。

在正常生产环境(即nginx,apache,Heroku等等)中运行此应用程序应该表明,当不安全时,使用httpshttp可以访问该应用程序,并且它不是当应用程序本身需要加密连接时,可以访问。

GEMFILE

gem 'plezi'

app.rb

#!/usr/bin/env ruby
require 'plezi'
class MyDemo
  # Http demo
  def index
     request.ssl? ? "Hello World (SSL/TLS)" : "Hello World (clear)"
  end
  # Websocket echo
  def on_message data
     write data # writes to the websocket
  end
end
route '/', MyDemo

使用明文运行应用程序:

./app.rb -p $PORT
# or static port, i.e.
# ./app.rb -p 3000

运行应用程序以进行加密连接:

./app.rb -p $PORT ssl
# or static port, i.e.
# ./app.rb -p 3000 ssl

如果您正确设置了生产代理或Heroku Dyno(或您正在使用的任何内容),该应用程序应适用于httphttpsws和{{ 1}}仅当它处于明文模式时才会在SSL模式下失败。

P.S。

可以在应用内设置SSL密钥和证书,以避免自签名证书,以防万一您想知道或认为这是问题。将以下行添加到您的应用中:

wss

另外,我是Plezi的作者,所以我对em-websockets感到有些偏见...