Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby WebSocket和EventMachine超时和错误恢复_Ruby_Heroku_Websocket_Eventmachine_Faye - Fatal编程技术网

Ruby WebSocket和EventMachine超时和错误恢复

Ruby WebSocket和EventMachine超时和错误恢复,ruby,heroku,websocket,eventmachine,faye,Ruby,Heroku,Websocket,Eventmachine,Faye,使用puma、faye websocket ruby和eventmachine,我试图实现一个websocket服务器,该服务器被扩展以支持使用redis.rb的频道。每个客户机将使用当前正在开发的路径提供一个通道:“/C#{random number}”。所有这些逻辑都需要驻留在服务器中,因为客户端将是基于微处理器的Python系统,不支持更高级别的库 作为起点,我的代码基于。一个主要的变化是将其配置为在WebSocket“打开”期间支持多个通道 代码在正常运行时工作。但是,通常当一个客户端断

使用puma、faye websocket ruby和eventmachine,我试图实现一个websocket服务器,该服务器被扩展以支持使用redis.rb的频道。每个客户机将使用当前正在开发的路径提供一个通道:“/C#{random number}”。所有这些逻辑都需要驻留在服务器中,因为客户端将是基于微处理器的Python系统,不支持更高级别的库

作为起点,我的代码基于。一个主要的变化是将其配置为在WebSocket“打开”期间支持多个通道

代码在正常运行时工作。但是,通常当一个客户端断开时,服务器会挂起,直到重新启动。我正在努力解决这个问题,但到目前为止还未能解决。最初,Heroku会抛出一个H12超时。我已经实现了机架超时。我尝试过在服务器内挽救超时,但这些超时从未触发。我在服务器中实现了一个“on error”事件,但它从未触发。最常见的情况是,服务器在重新启动之前一直处于关闭状态。客户端应该自己保护自己,但我需要服务器恢复并继续

config.ru:

require './app'
require './middlewares/myserver_backend'
require 'rack-timeout'
use Rack::Timeout, service_timeout: 20, wait_timeout: 30, wait_overtime: 60, service_past_wait: false
use Myserver::MyserverBackend
run Myserver::App
机架中间件“后端”:

Gemfile.lock文件:

GEM
  remote: https://rubygems.org/
  specs:
    activesupport (4.2.5.1)
      i18n (~> 0.7)
      json (~> 1.7, >= 1.7.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    eventmachine (1.2.0.1-x86-mingw32)
    faye-websocket (0.10.4)
      eventmachine (>= 0.12.0)
      websocket-driver (>= 0.5.1)
    i18n (0.7.0)
    json (1.8.3)
    json_pure (1.8.3)
    minitest (5.9.0)
    multi_json (1.12.1)
    oj (2.16.1)
    permessage_deflate (0.1.3)
    progressbar (0.21.0)
    puma (3.4.0)
    rack (1.6.4)
    rack-protection (1.5.3)
      rack
    rack-timeout (0.4.2)
    rake (11.2.2)
    redis (3.3.0)
    rollbar (2.11.5)
      multi_json
    sinatra (1.4.7)
      rack (~> 1.5)
      rack-protection (~> 1.4)
      tilt (>= 1.3, < 3)
    thread_safe (0.3.5)
    tilt (2.0.5)
    tzinfo (1.2.2)
      thread_safe (~> 0.1)
    websocket-driver (0.6.4)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.2)

PLATFORMS
  x86-mingw32

DEPENDENCIES
  activesupport (= 4.2.5.1)
  bundler
  faye-websocket
  json_pure
  oj (~> 2.16.0)
  permessage_deflate
  progressbar
  puma
  rack
  rack-timeout
  rake
  redis (>= 3.2.0)
  rollbar
  sinatra

RUBY VERSION
   ruby 2.2.4p230

BUNDLED WITH
   1.12.5
config/puma.rb:

env = ENV['OS'] == 'Windows_NT' ? 'development' : ENV['RACK_ENV']
if env.nil? || env == 'development' || env == 'test'
  concurrency = 0  # Set to zero to ensure single mode, not clustered mode
  max_threads = 1
end
# WEB_CONCURRENCY and RAILS_MAX_THREADS == 1 in Heroku for now.
concurrency ||= (ENV['WEB_CONCURRENCY'] || 2)
max_threads ||= (ENV['RAILS_MAX_THREADS'] || 5)
worker_timeout 15
workers Integer(concurrency)
threads_count = Integer(max_threads)
threads threads_count, threads_count

#preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

我需要做的是完成服务器的“关闭”事件。它需要清理一切,然后重新启动自己,但它没有这样做

然而,我不喜欢这个作为最终答案。问题是,为什么服务器会关闭商店,仅仅因为客户机被丢弃而终止并重新启动?难道没有更干净的方法来清除失败客户的碎屑吗?跟进:此修复确实回答了这个特定的问题,在任何情况下,完成onclose都解决了所述的问题。除了Redis事件之外,还进一步增强了客户端WebSocket事件的线程化,例如onclose只关闭客户端而不关闭服务器

新活动是:

  ws.on :close do |event|
    if @debug
      puts "MyserverBackend>> Close entered.  Last error:#{$!.class}:#{$!.to_s};Module:#{$0};Line:#{$.};"
      $@.each { |backtrace| puts backtrace }
      exit
    end
    @clients.each do |clients_ws, clients_channel|
      begin
        @redis.unsubscribe(clients_channel)
        rescue RuntimeError => exception
          unless exception.to_s == "Can't unsubscribe if not subscribed."
            raise
          end
        false
      end
    end
    @clients.delete_if { |clients_ws, clients_channel| clients_ws == ws }
    channel = URI.parse(event.target.url).path[1..URI.parse(event.target.url).path.length]
    puts "MyserverBackend>> Websocket closure for:#{channel}; Event code:#{event.code} Event reason:#{event.reason};"
    ws = nil
    app = Myserver::App
    myserver = MyserverBackend.new(app)
    myserver
  end
GEM
  remote: https://rubygems.org/
  specs:
    activesupport (4.2.5.1)
      i18n (~> 0.7)
      json (~> 1.7, >= 1.7.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    eventmachine (1.2.0.1-x86-mingw32)
    faye-websocket (0.10.4)
      eventmachine (>= 0.12.0)
      websocket-driver (>= 0.5.1)
    i18n (0.7.0)
    json (1.8.3)
    json_pure (1.8.3)
    minitest (5.9.0)
    multi_json (1.12.1)
    oj (2.16.1)
    permessage_deflate (0.1.3)
    progressbar (0.21.0)
    puma (3.4.0)
    rack (1.6.4)
    rack-protection (1.5.3)
      rack
    rack-timeout (0.4.2)
    rake (11.2.2)
    redis (3.3.0)
    rollbar (2.11.5)
      multi_json
    sinatra (1.4.7)
      rack (~> 1.5)
      rack-protection (~> 1.4)
      tilt (>= 1.3, < 3)
    thread_safe (0.3.5)
    tilt (2.0.5)
    tzinfo (1.2.2)
      thread_safe (~> 0.1)
    websocket-driver (0.6.4)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.2)

PLATFORMS
  x86-mingw32

DEPENDENCIES
  activesupport (= 4.2.5.1)
  bundler
  faye-websocket
  json_pure
  oj (~> 2.16.0)
  permessage_deflate
  progressbar
  puma
  rack
  rack-timeout
  rake
  redis (>= 3.2.0)
  rollbar
  sinatra

RUBY VERSION
   ruby 2.2.4p230

BUNDLED WITH
   1.12.5
ruby client.rb
20.098119 seconds;
[:close, 1002, "Error during WebSocket handshake: Unexpected response code: 500"]
20.07921 seconds;
[:close, 1002, "Error during WebSocket handshake: Unexpected response code: 500"]
20.075731 seconds;
[:close, 1002, "Error during WebSocket handshake: Unexpected response code: 500"]   
env = ENV['OS'] == 'Windows_NT' ? 'development' : ENV['RACK_ENV']
if env.nil? || env == 'development' || env == 'test'
  concurrency = 0  # Set to zero to ensure single mode, not clustered mode
  max_threads = 1
end
# WEB_CONCURRENCY and RAILS_MAX_THREADS == 1 in Heroku for now.
concurrency ||= (ENV['WEB_CONCURRENCY'] || 2)
max_threads ||= (ENV['RAILS_MAX_THREADS'] || 5)
worker_timeout 15
workers Integer(concurrency)
threads_count = Integer(max_threads)
threads threads_count, threads_count

#preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'
  ws.on :close do |event|
    if @debug
      puts "MyserverBackend>> Close entered.  Last error:#{$!.class}:#{$!.to_s};Module:#{$0};Line:#{$.};"
      $@.each { |backtrace| puts backtrace }
      exit
    end
    @clients.each do |clients_ws, clients_channel|
      begin
        @redis.unsubscribe(clients_channel)
        rescue RuntimeError => exception
          unless exception.to_s == "Can't unsubscribe if not subscribed."
            raise
          end
        false
      end
    end
    @clients.delete_if { |clients_ws, clients_channel| clients_ws == ws }
    channel = URI.parse(event.target.url).path[1..URI.parse(event.target.url).path.length]
    puts "MyserverBackend>> Websocket closure for:#{channel}; Event code:#{event.code} Event reason:#{event.reason};"
    ws = nil
    app = Myserver::App
    myserver = MyserverBackend.new(app)
    myserver
  end