Websocket 控制器未在 Rails 开发环境中自动加载
Posted
技术标签:
【中文标题】Websocket 控制器未在 Rails 开发环境中自动加载【英文标题】:Websocket controller not being auto loaded in Rails dev environment 【发布时间】:2018-07-06 18:15:48 【问题描述】:所以自从我开始使用websocket-rails
gem 以来,我一直有这个问题。显然它不能自动加载我的“广播控制器”并且阻止我在命令行上运行 rails 命令。
我过去常常通过注释掉事件文件并加载内容来解决这个问题。老实说,它是一个废话,有时它可以工作,有时它不会,但最近我还没有让它工作,我一直在尝试调试它一段时间,但老实说我被卡住了。
这只发生在开发中。
有人有什么想法吗?
这是错误堆栈:
/Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/dependencies.rb:513:in `load_missing_constant': Unable to autoload constant BroadcastsController, expected /Users/matt/Documents/sdcc_grp_buy/app/controllers/broadcasts_controller.rb to define it (LoadError)
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/dependencies.rb:203:in `const_missing'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/inflector/methods.rb:268:in `const_get'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/inflector/methods.rb:268:in `block in constantize'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/inflector/methods.rb:266:in `each'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/inflector/methods.rb:266:in `inject'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/inflector/methods.rb:266:in `constantize'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/core_ext/string/inflections.rb:66:in `constantize'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:179:in `constantize_controller'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:172:in `validate_string_target'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:153:in `validate_target'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:102:in `store'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:60:in `subscribe'
from /Users/matt/Documents/sdcc_grp_buy/config/events.rb:20:in `block in <top (required)>'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:55:in `instance_eval'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:55:in `evaluate'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/event_map.rb:30:in `initialize'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/dispatcher.rb:13:in `new'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/dispatcher.rb:13:in `initialize'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/connection_manager.rb:32:in `new'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/websocket_rails/connection_manager.rb:32:in `initialize'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/rails/config/routes.rb:3:in `new'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/rails/config/routes.rb:3:in `block in <top (required)>'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/actionpack-5.0.7/lib/action_dispatch/routing/route_set.rb:391:in `instance_exec'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/actionpack-5.0.7/lib/action_dispatch/routing/route_set.rb:391:in `eval_block'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/actionpack-5.0.7/lib/action_dispatch/routing/route_set.rb:373:in `draw'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/bundler/gems/websocket-rails-3d4bc7cb73e2/lib/rails/config/routes.rb:1:in `<top (required)>'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/dependencies.rb:287:in `load'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/dependencies.rb:287:in `block in load'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/dependencies.rb:259:in `load_dependency'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/dependencies.rb:287:in `load'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/routes_reloader.rb:40:in `block in load_paths'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/routes_reloader.rb:40:in `each'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/routes_reloader.rb:40:in `load_paths'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/routes_reloader.rb:16:in `reload!'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/routes_reloader.rb:26:in `block in updater'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/file_update_checker.rb:77:in `execute'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/routes_reloader.rb:7:in `execute'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/railties-5.0.7/lib/rails/application/finisher.rb:132:in `block (2 levels) in <module:Finisher>'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:396:in `instance_exec'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:396:in `block in make_lambda'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:169:in `block (2 levels) in halting'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:547:in `block (2 levels) in default_terminator'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:546:in `catch'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:546:in `block in default_terminator'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:170:in `block in halting'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:454:in `block in call'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:454:in `each'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:454:in `call'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:101:in `__run_callbacks__'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:750:in `_run_run_callbacks'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/callbacks.rb:90:in `run_callbacks'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/execution_wrapper.rb:108:in `run!'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/reloader.rb:113:in `run!'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/reloader.rb:48:in `block (2 levels) in reload!'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/reloader.rb:46:in `tap'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/reloader.rb:46:in `block in reload!'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/execution_wrapper.rb:85:in `wrap'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/activesupport-5.0.7/lib/active_support/reloader.rb:45:in `reload!'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/spring-2.0.2/lib/spring/application.rb:164:in `serve'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/spring-2.0.2/lib/spring/application.rb:141:in `block in run'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/spring-2.0.2/lib/spring/application.rb:135:in `loop'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/spring-2.0.2/lib/spring/application.rb:135:in `run'
from /Users/matt/Documents/sdcc_grp_buy/vendor/bundle/ruby/2.4.0/gems/spring-2.0.2/lib/spring/application/boot.rb:19:in `<top (required)>'
from /usr/local/Cellar/ruby/2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /usr/local/Cellar/ruby/2.4.0/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from -e:1:in `<main>'`
这就是/Users/matt/Documents/sdcc_grp_buy/app/controllers/broadcasts_controller.rb
的样子:
class BroadcastsController < WebsocketRails::BaseController
def register_member_to_group
room = message[:room]
member_group_id = message[:member_group_id]
connection = message[:connection]
member_id = message[:member_id]
grp = Group.find(room)
number = grp.member_groups.count
WebsocketRails["group_#room"].trigger('member_registered', room: room, member_group_id: member_group_id, member_id: member_id, connection_id: connection, :num_of_ppl => number)
end
def check_in_member
room = message[:room]
member_id = message[:member_id]
connection = message[:connection]
member = Member.find(member_id)
member.checked_in_date = Date.today
if member.save
WebsocketRails["global"].trigger('check_in_member', room: room, member_id: member_id, connection_id: connection )
end
end
def check_out_member
room = message[:room]
member_id = message[:member_id]
connection = message[:connection]
member = Member.find(member_id)
member.checked_in_date = Date.today - 25.hours
if member.save
WebsocketRails["global"].trigger('check_out_member', room: room, member_id: member_id, connection_id: connection )
end
end
def delete_member_from_group
room = message[:room]
member_group_id = message[:member_group_id]
connection = message[:connection]
grp = Group.find(room)
number = grp.member_groups.count
WebsocketRails["group_#room"].trigger('unregister_member', room: room, member_group_id: member_group_id, connection_id: connection, :num_of_ppl => number )
end
def mark_member_as_covered_for_all_groups
member_id = message[:member_id]
end
def group_updated
group_id = message[:room]
count = message[:count]
total = count.split('/')[1]
covered = count.split('/')[0]
if covered == total
complete = true
else
complete = false
end
obj =
group_id: group_id,
count: count,
complete: complete
WebsocketRails["global"].trigger('group_updated', obj)
end
def cover_member_for_group
room = message[:group_id]
member_group_id = message[:member_group_id]
member_id = MemberGroup.find(message[:member_group_id]).member.id
connection = message[:connection]
WebsocketRails["global"].trigger('member_covered', member_id: member_id, member_group_id: member_group_id, group_id: room, connection_id: connection)
end
def someone_typing
room = message[:room]
connection = message[:connection]
WebsocketRails["group_#room"].trigger('someone_typing', room: room, connection_id: connection)
end
def deactivate_member
member = Member.find(message[:member_id])
member.active = false
member.sponsor_id = nil
connection = message[:connection]
# maybe i need to loop in the JS and not in the controller
if member.save
WebsocketRails["global"].trigger('deactivate_member', :member_id => member.id,connection_id: connection )
else
puts 'ERROR'
end
end
def activate_member
member = Member.find(message[:member_id])
member.active = true
member.sponsor_id = current_user.id
connection = message[:connection]
# maybe i need to loop in the JS and not in the controller
if member.save
WebsocketRails["global"].trigger('activate_member', :member_id => member.id,connection_id: connection )
else
puts 'error'
puts member.errors.full_messages.join(',')
end
end
def send_chat_message
type = message[:type]
room = message[:room]
message_id = message[:message]
user_id = current_user.id
connection = message[:connection]
if type == 'group'
WebsocketRails["group_#room"].trigger('add_room_message', room: room, message_id: message_id, user_id: message[:user_id], connection_id: connection)
else
WebsocketRails["global"].trigger('add_global_message', message_id: message_id, user_id: message[:user_id], connection_id: connection)
end
end
end
这就是我的 events.rb 文件的样子:
WebsocketRails::EventMap.describe do
# You can use this file to map incoming events to controller actions.
# One event can be mapped to any number of controller actions. The
# actions will be executed in the order they were subscribed.
# subscribe :client_connected, 'groups#new_user'
#
# Uncomment and edit the next line to handle the client connected event:
# subscribe :client_connected, :to => Controller, :with_method => :method_name
#
# Here is an example of mapping namespaced events:
# namespace :product do
# subscribe :new, :to => ProductController, :with_method => :new_product
# end
# namespace :chatroom do
# subscribe :create_room, "groups#create_room"
# subscribe :update_members, 'groups#update'
# end
# namespace :members do
subscribe :register_member, "broadcasts#register_member_to_group"
subscribe :unregister, "broadcasts#delete_member_from_group"
subscribe :cover_member, "broadcasts#cover_member_for_group"
subscribe :activate_member, "broadcasts#activate_member"
subscribe :deactivate_member, "broadcasts#deactivate_member"
subscribe :send_chat_message, "broadcasts#send_chat_message"
subscribe :someone_typing, "broadcasts#someone_typing"
subscribe :group_updated, "broadcasts#group_updated"
subscribe :check_in_member, "broadcasts#check_in_member"
subscribe :check_out_member, "broadcasts#check_out_member"
# end
# The above will handle an event triggered on the client like `product.new`.
end
宝石文件:
source 'https://rubygems.org'
# git_source(:github) do |repo_name|
# repo_name = "#repo_name/#repo_name" unless repo_name.include?("/")
# "https://github.com/#repo_name.git"
# end
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.4'
# Use sqlite3 as the database for Active Record
# gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for javascript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
# Use jquery as the JavaScript library
gem 'jquery-rails'
gem 'jquery-ui-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
gem 'devise'
gem 'faker'
gem 'omniauth'
gem 'activerecord-session_store'
# rails generate active_record:session_migration
# gem 'omniauth-facebook', '1.4.0'
gem 'omniauth-facebook'
gem 'bootstrap-sass', '~> 3.2.0'
gem 'autoprefixer-rails'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'``
gem 'dotenv-rails'
gem 'will_paginate', '~> 3.0.6'
gem 'redis', '~> 3.0'
# gem 'redis-namespace'
# Use Unicorn as the app server
# gem 'unicorn'
# gem 'websocket-rails'
gem 'react-rails'
gem 'twilio-ruby', '~> 5.10.5'
# gem 'webpacker'
gem 'webpacker', '~> 3.5'
gem 'websocket-rails', github: 'recurser/websocket-rails', branch: 'bugfix/388-latest-faye-websocket'
# gem 'websocket-rails'
# gem 'websocket-rails', github: 'moaa/websocket-rails', branch: 'threadsocket-rails'
# gem 'aws-sdk', '~> 2'
# gem 'aws-sdk-rails'
# gem 'csv'
group :development, :test do
gem 'sqlite3'
gem 'byebug'
gem 'listen'
# Access an IRB console on exception pages or by using <%= console %> in views
gem 'web-console', '~> 2.0'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
end
group :production do
# gem 'websocket-rails' #, github: 'recurser/websocket-rails', branch: 'bugfix/388-latest-faye-websocket'
gem 'pg'
# gem 'mysql2'
gem 'rails_12factor', '0.0.2'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
# gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
开发.rb:
Rails.application.configure do
# Verifies that versions and hashed value of the package contents in the project's package.json
config.webpacker.check_yarn_integrity = true
# Verifies that versions and hashed value of the package contents in the project's package.json
config.webpacker.check_yarn_integrity = true
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
config.action_mailer.perform_deliveries = true
# Enable/disable caching. By default caching is disabled.
if Rails.root.join('tmp/caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.cache_store = :memory_store
config.public_file_server.headers =
'Cache-Control' => 'public, max-age=172800'
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = false
# Suppress logger output for asset requests.
config.assets.quiet = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
config.action_mailer.smtp_settings =
:address => "email-smtp.us-west-2.amazonaws.com",
:port => 587,
:user_name => ENV["SES_SMTP_USERNAME"], #Your SMTP user
:password => ENV["SES_SMTP_PASSWORD"], #Your SMTP password
:authentication => :login,
:enable_starttls_auto => true
end
【问题讨论】:
【参考方案1】:想通了,弹簧服务器挂了,这样做解决了:
spring stop
参考:"rails generate" not working
【讨论】:
以上是关于Websocket 控制器未在 Rails 开发环境中自动加载的主要内容,如果未能解决你的问题,请参考以下文章
SignalR Core 未在 Azure 应用服务中使用 Websocket
凭证文件未在 Amazon Linux 上读取 Rails 6.1