actioncable 5.2.8.1 → 6.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -112
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +1 -544
  5. data/app/assets/javascripts/action_cable.js +492 -0
  6. data/lib/action_cable/channel/base.rb +5 -1
  7. data/lib/action_cable/channel/test_case.rb +312 -0
  8. data/lib/action_cable/channel.rb +1 -0
  9. data/lib/action_cable/connection/authorization.rb +1 -1
  10. data/lib/action_cable/connection/base.rb +9 -7
  11. data/lib/action_cable/connection/message_buffer.rb +1 -4
  12. data/lib/action_cable/connection/stream.rb +4 -2
  13. data/lib/action_cable/connection/subscriptions.rb +1 -5
  14. data/lib/action_cable/connection/test_case.rb +236 -0
  15. data/lib/action_cable/connection/web_socket.rb +1 -3
  16. data/lib/action_cable/connection.rb +1 -0
  17. data/lib/action_cable/gem_version.rb +4 -4
  18. data/lib/action_cable/server/base.rb +3 -1
  19. data/lib/action_cable/server/worker.rb +5 -7
  20. data/lib/action_cable/subscription_adapter/postgresql.rb +24 -8
  21. data/lib/action_cable/subscription_adapter/redis.rb +2 -1
  22. data/lib/action_cable/subscription_adapter/test.rb +40 -0
  23. data/lib/action_cable/subscription_adapter.rb +1 -0
  24. data/lib/action_cable/test_case.rb +11 -0
  25. data/lib/action_cable/test_helper.rb +133 -0
  26. data/lib/action_cable.rb +15 -7
  27. data/lib/rails/generators/channel/USAGE +4 -5
  28. data/lib/rails/generators/channel/channel_generator.rb +6 -3
  29. data/lib/rails/generators/channel/templates/{assets → javascript}/channel.js.tt +3 -1
  30. data/lib/rails/generators/channel/templates/{assets/cable.js.tt → javascript/consumer.js.tt} +2 -9
  31. data/lib/rails/generators/channel/templates/javascript/index.js.tt +5 -0
  32. data/lib/rails/generators/test_unit/channel_generator.rb +20 -0
  33. data/lib/rails/generators/test_unit/templates/channel_test.rb.tt +8 -0
  34. metadata +24 -17
  35. data/lib/assets/compiled/action_cable.js +0 -601
  36. data/lib/rails/generators/channel/templates/assets/channel.coffee.tt +0 -14
@@ -36,7 +36,9 @@ module ActionCable
36
36
  end
37
37
 
38
38
  def restart
39
- connections.each(&:close)
39
+ connections.each do |connection|
40
+ connection.close(reason: ActionCable::INTERNAL[:disconnect_reasons][:server_restart])
41
+ end
40
42
 
41
43
  @mutex.synchronize do
42
44
  # Shutdown the worker pool
@@ -56,14 +56,12 @@ module ActionCable
56
56
 
57
57
  def invoke(receiver, method, *args, connection:, &block)
58
58
  work(connection) do
59
- begin
60
- receiver.send method, *args, &block
61
- rescue Exception => e
62
- logger.error "There was an exception - #{e.class}(#{e.message})"
63
- logger.error e.backtrace.join("\n")
59
+ receiver.send method, *args, &block
60
+ rescue Exception => e
61
+ logger.error "There was an exception - #{e.class}(#{e.message})"
62
+ logger.error e.backtrace.join("\n")
64
63
 
65
- receiver.handle_exception if receiver.respond_to?(:handle_exception)
66
- end
64
+ receiver.handle_exception if receiver.respond_to?(:handle_exception)
67
65
  end
68
66
  end
69
67
 
@@ -14,7 +14,7 @@ module ActionCable
14
14
  end
15
15
 
16
16
  def broadcast(channel, payload)
17
- with_connection do |pg_conn|
17
+ with_broadcast_connection do |pg_conn|
18
18
  pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel_identifier(channel))}, '#{pg_conn.escape_string(payload)}'")
19
19
  end
20
20
  end
@@ -31,14 +31,24 @@ module ActionCable
31
31
  listener.shutdown
32
32
  end
33
33
 
34
- def with_connection(&block) # :nodoc:
35
- ActiveRecord::Base.connection_pool.with_connection do |ar_conn|
36
- pg_conn = ar_conn.raw_connection
34
+ def with_subscriptions_connection(&block) # :nodoc:
35
+ ar_conn = ActiveRecord::Base.connection_pool.checkout.tap do |conn|
36
+ # Action Cable is taking ownership over this database connection, and
37
+ # will perform the necessary cleanup tasks
38
+ ActiveRecord::Base.connection_pool.remove(conn)
39
+ end
40
+ pg_conn = ar_conn.raw_connection
37
41
 
38
- unless pg_conn.is_a?(PG::Connection)
39
- raise "The Active Record database must be PostgreSQL in order to use the PostgreSQL Action Cable storage adapter"
40
- end
42
+ verify!(pg_conn)
43
+ yield pg_conn
44
+ ensure
45
+ ar_conn.disconnect!
46
+ end
41
47
 
48
+ def with_broadcast_connection(&block) # :nodoc:
49
+ ActiveRecord::Base.connection_pool.with_connection do |ar_conn|
50
+ pg_conn = ar_conn.raw_connection
51
+ verify!(pg_conn)
42
52
  yield pg_conn
43
53
  end
44
54
  end
@@ -52,6 +62,12 @@ module ActionCable
52
62
  @listener || @server.mutex.synchronize { @listener ||= Listener.new(self, @server.event_loop) }
53
63
  end
54
64
 
65
+ def verify!(pg_conn)
66
+ unless pg_conn.is_a?(PG::Connection)
67
+ raise "The Active Record database must be PostgreSQL in order to use the PostgreSQL Action Cable storage adapter"
68
+ end
69
+ end
70
+
55
71
  class Listener < SubscriberMap
56
72
  def initialize(adapter, event_loop)
57
73
  super()
@@ -67,7 +83,7 @@ module ActionCable
67
83
  end
68
84
 
69
85
  def listen
70
- @adapter.with_connection do |pg_conn|
86
+ @adapter.with_subscriptions_connection do |pg_conn|
71
87
  catch :shutdown do
72
88
  loop do
73
89
  until @queue.empty?
@@ -13,7 +13,8 @@ module ActionCable
13
13
  # Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem.
14
14
  # This is needed, for example, when using Makara proxies for distributed Redis.
15
15
  cattr_accessor :redis_connector, default: ->(config) do
16
- ::Redis.new(config.slice(:url, :host, :port, :db, :password))
16
+ config[:id] ||= "ActionCable-PID-#{$$}"
17
+ ::Redis.new(config.slice(:url, :host, :port, :db, :password, :id))
17
18
  end
18
19
 
19
20
  def initialize(*)
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "async"
4
+
5
+ module ActionCable
6
+ module SubscriptionAdapter
7
+ # == Test adapter for Action Cable
8
+ #
9
+ # The test adapter should be used only in testing. Along with
10
+ # <tt>ActionCable::TestHelper</tt> it makes a great tool to test your Rails application.
11
+ #
12
+ # To use the test adapter set +adapter+ value to +test+ in your +config/cable.yml+ file.
13
+ #
14
+ # NOTE: Test adapter extends the <tt>ActionCable::SubscriptionsAdapter::Async</tt> adapter,
15
+ # so it could be used in system tests too.
16
+ class Test < Async
17
+ def broadcast(channel, payload)
18
+ broadcasts(channel) << payload
19
+ super
20
+ end
21
+
22
+ def broadcasts(channel)
23
+ channels_data[channel] ||= []
24
+ end
25
+
26
+ def clear_messages(channel)
27
+ channels_data[channel] = []
28
+ end
29
+
30
+ def clear
31
+ @channels_data = nil
32
+ end
33
+
34
+ private
35
+ def channels_data
36
+ @channels_data ||= {}
37
+ end
38
+ end
39
+ end
40
+ end
@@ -5,6 +5,7 @@ module ActionCable
5
5
  extend ActiveSupport::Autoload
6
6
 
7
7
  autoload :Base
8
+ autoload :Test
8
9
  autoload :SubscriberMap
9
10
  autoload :ChannelPrefix
10
11
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/test_case"
4
+
5
+ module ActionCable
6
+ class TestCase < ActiveSupport::TestCase
7
+ include ActionCable::TestHelper
8
+
9
+ ActiveSupport.run_load_hooks(:action_cable_test_case, self)
10
+ end
11
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionCable
4
+ # Provides helper methods for testing Action Cable broadcasting
5
+ module TestHelper
6
+ def before_setup # :nodoc:
7
+ server = ActionCable.server
8
+ test_adapter = ActionCable::SubscriptionAdapter::Test.new(server)
9
+
10
+ @old_pubsub_adapter = server.pubsub
11
+
12
+ server.instance_variable_set(:@pubsub, test_adapter)
13
+ super
14
+ end
15
+
16
+ def after_teardown # :nodoc:
17
+ super
18
+ ActionCable.server.instance_variable_set(:@pubsub, @old_pubsub_adapter)
19
+ end
20
+
21
+ # Asserts that the number of broadcasted messages to the stream matches the given number.
22
+ #
23
+ # def test_broadcasts
24
+ # assert_broadcasts 'messages', 0
25
+ # ActionCable.server.broadcast 'messages', { text: 'hello' }
26
+ # assert_broadcasts 'messages', 1
27
+ # ActionCable.server.broadcast 'messages', { text: 'world' }
28
+ # assert_broadcasts 'messages', 2
29
+ # end
30
+ #
31
+ # If a block is passed, that block should cause the specified number of
32
+ # messages to be broadcasted.
33
+ #
34
+ # def test_broadcasts_again
35
+ # assert_broadcasts('messages', 1) do
36
+ # ActionCable.server.broadcast 'messages', { text: 'hello' }
37
+ # end
38
+ #
39
+ # assert_broadcasts('messages', 2) do
40
+ # ActionCable.server.broadcast 'messages', { text: 'hi' }
41
+ # ActionCable.server.broadcast 'messages', { text: 'how are you?' }
42
+ # end
43
+ # end
44
+ #
45
+ def assert_broadcasts(stream, number)
46
+ if block_given?
47
+ original_count = broadcasts_size(stream)
48
+ yield
49
+ new_count = broadcasts_size(stream)
50
+ actual_count = new_count - original_count
51
+ else
52
+ actual_count = broadcasts_size(stream)
53
+ end
54
+
55
+ assert_equal number, actual_count, "#{number} broadcasts to #{stream} expected, but #{actual_count} were sent"
56
+ end
57
+
58
+ # Asserts that no messages have been sent to the stream.
59
+ #
60
+ # def test_no_broadcasts
61
+ # assert_no_broadcasts 'messages'
62
+ # ActionCable.server.broadcast 'messages', { text: 'hi' }
63
+ # assert_broadcasts 'messages', 1
64
+ # end
65
+ #
66
+ # If a block is passed, that block should not cause any message to be sent.
67
+ #
68
+ # def test_broadcasts_again
69
+ # assert_no_broadcasts 'messages' do
70
+ # # No job messages should be sent from this block
71
+ # end
72
+ # end
73
+ #
74
+ # Note: This assertion is simply a shortcut for:
75
+ #
76
+ # assert_broadcasts 'messages', 0, &block
77
+ #
78
+ def assert_no_broadcasts(stream, &block)
79
+ assert_broadcasts stream, 0, &block
80
+ end
81
+
82
+ # Asserts that the specified message has been sent to the stream.
83
+ #
84
+ # def test_assert_transmitted_message
85
+ # ActionCable.server.broadcast 'messages', text: 'hello'
86
+ # assert_broadcast_on('messages', text: 'hello')
87
+ # end
88
+ #
89
+ # If a block is passed, that block should cause a message with the specified data to be sent.
90
+ #
91
+ # def test_assert_broadcast_on_again
92
+ # assert_broadcast_on('messages', text: 'hello') do
93
+ # ActionCable.server.broadcast 'messages', text: 'hello'
94
+ # end
95
+ # end
96
+ #
97
+ def assert_broadcast_on(stream, data)
98
+ # Encode to JSON and back–we want to use this value to compare
99
+ # with decoded JSON.
100
+ # Comparing JSON strings doesn't work due to the order if the keys.
101
+ serialized_msg =
102
+ ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(data))
103
+
104
+ new_messages = broadcasts(stream)
105
+ if block_given?
106
+ old_messages = new_messages
107
+ clear_messages(stream)
108
+
109
+ yield
110
+ new_messages = broadcasts(stream)
111
+ clear_messages(stream)
112
+
113
+ # Restore all sent messages
114
+ (old_messages + new_messages).each { |m| pubsub_adapter.broadcast(stream, m) }
115
+ end
116
+
117
+ message = new_messages.find { |msg| ActiveSupport::JSON.decode(msg) == serialized_msg }
118
+
119
+ assert message, "No messages sent with #{data} to #{stream}"
120
+ end
121
+
122
+ def pubsub_adapter # :nodoc:
123
+ ActionCable.server.pubsub
124
+ end
125
+
126
+ delegate :broadcasts, :clear_messages, to: :pubsub_adapter
127
+
128
+ private
129
+ def broadcasts_size(channel)
130
+ broadcasts(channel).size
131
+ end
132
+ end
133
+ end
data/lib/action_cable.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2015-2018 Basecamp, LLC
4
+ # Copyright (c) 2015-2019 Basecamp, LLC
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -32,13 +32,19 @@ module ActionCable
32
32
 
33
33
  INTERNAL = {
34
34
  message_types: {
35
- welcome: "welcome".freeze,
36
- ping: "ping".freeze,
37
- confirmation: "confirm_subscription".freeze,
38
- rejection: "reject_subscription".freeze
35
+ welcome: "welcome",
36
+ disconnect: "disconnect",
37
+ ping: "ping",
38
+ confirmation: "confirm_subscription",
39
+ rejection: "reject_subscription"
39
40
  },
40
- default_mount_path: "/cable".freeze,
41
- protocols: ["actioncable-v1-json".freeze, "actioncable-unsupported".freeze].freeze
41
+ disconnect_reasons: {
42
+ unauthorized: "unauthorized",
43
+ invalid_request: "invalid_request",
44
+ server_restart: "server_restart"
45
+ },
46
+ default_mount_path: "/cable",
47
+ protocols: ["actioncable-v1-json", "actioncable-unsupported"].freeze
42
48
  }
43
49
 
44
50
  # Singleton instance of the server
@@ -51,4 +57,6 @@ module ActionCable
51
57
  autoload :Channel
52
58
  autoload :RemoteConnections
53
59
  autoload :SubscriptionAdapter
60
+ autoload :TestHelper
61
+ autoload :TestCase
54
62
  end
@@ -1,14 +1,13 @@
1
1
  Description:
2
2
  ============
3
- Stubs out a new cable channel for the server (in Ruby) and client (in CoffeeScript).
3
+ Stubs out a new cable channel for the server (in Ruby) and client (in JavaScript).
4
4
  Pass the channel name, either CamelCased or under_scored, and an optional list of channel actions as arguments.
5
5
 
6
- Note: Turn on the cable connection in app/assets/javascripts/cable.js after generating any channels.
7
-
8
6
  Example:
9
7
  ========
10
8
  rails generate channel Chat speak
11
9
 
12
- creates a Chat channel class and CoffeeScript asset:
10
+ creates a Chat channel class, test and JavaScript asset:
13
11
  Channel: app/channels/chat_channel.rb
14
- Assets: app/assets/javascripts/channels/chat.coffee
12
+ Test: test/channels/chat_channel_test.rb
13
+ Assets: app/javascript/channels/chat_channel.js
@@ -11,15 +11,18 @@ module Rails
11
11
 
12
12
  check_class_collision suffix: "Channel"
13
13
 
14
+ hook_for :test_framework
15
+
14
16
  def create_channel_file
15
17
  template "channel.rb", File.join("app/channels", class_path, "#{file_name}_channel.rb")
16
18
 
17
19
  if options[:assets]
18
20
  if behavior == :invoke
19
- template "assets/cable.js", "app/assets/javascripts/cable.js"
21
+ template "javascript/index.js", "app/javascript/channels/index.js"
22
+ template "javascript/consumer.js", "app/javascript/channels/consumer.js"
20
23
  end
21
24
 
22
- js_template "assets/channel", File.join("app/assets/javascripts/channels", class_path, "#{file_name}")
25
+ js_template "javascript/channel", File.join("app/javascript/channels", class_path, "#{file_name}_channel")
23
26
  end
24
27
 
25
28
  generate_application_cable_files
@@ -27,7 +30,7 @@ module Rails
27
30
 
28
31
  private
29
32
  def file_name
30
- @_file_name ||= super.gsub(/_channel/i, "")
33
+ @_file_name ||= super.sub(/_channel\z/i, "")
31
34
  end
32
35
 
33
36
  # FIXME: Change these files to symlinks once RubyGems 2.5.0 is required.
@@ -1,4 +1,6 @@
1
- App.<%= class_name.underscore %> = App.cable.subscriptions.create("<%= class_name %>Channel", {
1
+ import consumer from "./consumer"
2
+
3
+ consumer.subscriptions.create("<%= class_name %>Channel", {
2
4
  connected: function() {
3
5
  // Called when the subscription is ready for use on the server
4
6
  },
@@ -1,13 +1,6 @@
1
1
  // Action Cable provides the framework to deal with WebSockets in Rails.
2
2
  // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3
- //
4
- //= require action_cable
5
- //= require_self
6
- //= require_tree ./channels
7
3
 
8
- (function() {
9
- this.App || (this.App = {});
4
+ import ActionCable from "@rails/actioncable"
10
5
 
11
- App.cable = ActionCable.createConsumer();
12
-
13
- }).call(this);
6
+ export default ActionCable.createConsumer()
@@ -0,0 +1,5 @@
1
+ // Load all the channels within this directory and all subdirectories.
2
+ // Channel files must be named *_channel.js.
3
+
4
+ const channels = require.context('.', true, /_channel\.js$/)
5
+ channels.keys().forEach(channels)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TestUnit
4
+ module Generators
5
+ class ChannelGenerator < ::Rails::Generators::NamedBase
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ check_class_collision suffix: "ChannelTest"
9
+
10
+ def create_test_files
11
+ template "channel_test.rb", File.join("test/channels", class_path, "#{file_name}_channel_test.rb")
12
+ end
13
+
14
+ private
15
+ def file_name # :doc:
16
+ @_file_name ||= super.sub(/_channel\z/i, "")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ require "test_helper"
2
+
3
+ class <%= class_name %>ChannelTest < ActionCable::Channel::TestCase
4
+ # test "subscribes" do
5
+ # subscribe
6
+ # assert subscription.confirmed?
7
+ # end
8
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actioncable
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.8.1
4
+ version: 6.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
8
8
  - David Heinemeier Hansson
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-07-12 00:00:00.000000000 Z
12
+ date: 2019-01-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 5.2.8.1
20
+ version: 6.0.0.beta1
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 5.2.8.1
27
+ version: 6.0.0.beta1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: nio4r
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +65,7 @@ files:
65
65
  - CHANGELOG.md
66
66
  - MIT-LICENSE
67
67
  - README.md
68
+ - app/assets/javascripts/action_cable.js
68
69
  - lib/action_cable.rb
69
70
  - lib/action_cable/channel.rb
70
71
  - lib/action_cable/channel/base.rb
@@ -73,6 +74,7 @@ files:
73
74
  - lib/action_cable/channel/naming.rb
74
75
  - lib/action_cable/channel/periodic_timers.rb
75
76
  - lib/action_cable/channel/streams.rb
77
+ - lib/action_cable/channel/test_case.rb
76
78
  - lib/action_cable/connection.rb
77
79
  - lib/action_cable/connection/authorization.rb
78
80
  - lib/action_cable/connection/base.rb
@@ -84,6 +86,7 @@ files:
84
86
  - lib/action_cable/connection/stream_event_loop.rb
85
87
  - lib/action_cable/connection/subscriptions.rb
86
88
  - lib/action_cable/connection/tagged_logger_proxy.rb
89
+ - lib/action_cable/connection/test_case.rb
87
90
  - lib/action_cable/connection/web_socket.rb
88
91
  - lib/action_cable/engine.rb
89
92
  - lib/action_cable/gem_version.rb
@@ -104,23 +107,27 @@ files:
104
107
  - lib/action_cable/subscription_adapter/postgresql.rb
105
108
  - lib/action_cable/subscription_adapter/redis.rb
106
109
  - lib/action_cable/subscription_adapter/subscriber_map.rb
110
+ - lib/action_cable/subscription_adapter/test.rb
111
+ - lib/action_cable/test_case.rb
112
+ - lib/action_cable/test_helper.rb
107
113
  - lib/action_cable/version.rb
108
- - lib/assets/compiled/action_cable.js
109
114
  - lib/rails/generators/channel/USAGE
110
115
  - lib/rails/generators/channel/channel_generator.rb
111
116
  - lib/rails/generators/channel/templates/application_cable/channel.rb.tt
112
117
  - lib/rails/generators/channel/templates/application_cable/connection.rb.tt
113
- - lib/rails/generators/channel/templates/assets/cable.js.tt
114
- - lib/rails/generators/channel/templates/assets/channel.coffee.tt
115
- - lib/rails/generators/channel/templates/assets/channel.js.tt
116
118
  - lib/rails/generators/channel/templates/channel.rb.tt
119
+ - lib/rails/generators/channel/templates/javascript/channel.js.tt
120
+ - lib/rails/generators/channel/templates/javascript/consumer.js.tt
121
+ - lib/rails/generators/channel/templates/javascript/index.js.tt
122
+ - lib/rails/generators/test_unit/channel_generator.rb
123
+ - lib/rails/generators/test_unit/templates/channel_test.rb.tt
117
124
  homepage: http://rubyonrails.org
118
125
  licenses:
119
126
  - MIT
120
127
  metadata:
121
- source_code_uri: https://github.com/rails/rails/tree/v5.2.8.1/actioncable
122
- changelog_uri: https://github.com/rails/rails/blob/v5.2.8.1/actioncable/CHANGELOG.md
123
- post_install_message:
128
+ source_code_uri: https://github.com/rails/rails/tree/v6.0.0.beta1/actioncable
129
+ changelog_uri: https://github.com/rails/rails/blob/v6.0.0.beta1/actioncable/CHANGELOG.md
130
+ post_install_message:
124
131
  rdoc_options: []
125
132
  require_paths:
126
133
  - lib
@@ -128,15 +135,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
128
135
  requirements:
129
136
  - - ">="
130
137
  - !ruby/object:Gem::Version
131
- version: 2.2.2
138
+ version: 2.5.0
132
139
  required_rubygems_version: !ruby/object:Gem::Requirement
133
140
  requirements:
134
- - - ">="
141
+ - - ">"
135
142
  - !ruby/object:Gem::Version
136
- version: '0'
143
+ version: 1.3.1
137
144
  requirements: []
138
- rubygems_version: 3.3.3
139
- signing_key:
145
+ rubygems_version: 3.0.1
146
+ signing_key:
140
147
  specification_version: 4
141
148
  summary: WebSocket framework for Rails.
142
149
  test_files: []