litecable 0.4.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +32 -1
  3. data/LICENSE.txt +1 -1
  4. data/README.md +30 -28
  5. data/lib/lite_cable.rb +23 -2
  6. data/lib/lite_cable/anycable.rb +21 -12
  7. data/lib/lite_cable/broadcast_adapters.rb +35 -0
  8. data/lib/lite_cable/broadcast_adapters/any_cable.rb +11 -0
  9. data/lib/lite_cable/broadcast_adapters/base.rb +17 -0
  10. data/lib/lite_cable/broadcast_adapters/memory.rb +11 -0
  11. data/lib/lite_cable/channel.rb +1 -0
  12. data/lib/lite_cable/channel/base.rb +2 -0
  13. data/lib/lite_cable/channel/registry.rb +3 -0
  14. data/lib/lite_cable/channel/streams.rb +1 -0
  15. data/lib/lite_cable/coders.rb +1 -0
  16. data/lib/lite_cable/coders/json.rb +1 -0
  17. data/lib/lite_cable/coders/raw.rb +1 -0
  18. data/lib/lite_cable/config.rb +8 -6
  19. data/lib/lite_cable/connection.rb +1 -0
  20. data/lib/lite_cable/connection/authorization.rb +1 -0
  21. data/lib/lite_cable/connection/base.rb +2 -0
  22. data/lib/lite_cable/connection/identification.rb +3 -0
  23. data/lib/lite_cable/connection/streams.rb +1 -0
  24. data/lib/lite_cable/connection/subscriptions.rb +5 -3
  25. data/lib/lite_cable/internal.rb +1 -0
  26. data/lib/lite_cable/logging.rb +3 -1
  27. data/lib/lite_cable/server.rb +1 -6
  28. data/lib/lite_cable/server/client_socket.rb +1 -0
  29. data/lib/lite_cable/server/client_socket/base.rb +16 -21
  30. data/lib/lite_cable/server/client_socket/subscriptions.rb +3 -2
  31. data/lib/lite_cable/server/heart_beat.rb +4 -1
  32. data/lib/lite_cable/server/middleware.rb +11 -10
  33. data/lib/lite_cable/server/subscribers_map.rb +3 -0
  34. data/lib/lite_cable/version.rb +2 -1
  35. data/lib/litecable.rb +1 -0
  36. metadata +31 -50
  37. data/.gitignore +0 -40
  38. data/.rubocop.yml +0 -63
  39. data/.travis.yml +0 -7
  40. data/Gemfile +0 -4
  41. data/Rakefile +0 -6
  42. data/bin/console +0 -14
  43. data/bin/setup +0 -8
  44. data/circle.yml +0 -8
  45. data/examples/sinatra/Gemfile +0 -16
  46. data/examples/sinatra/Procfile +0 -3
  47. data/examples/sinatra/README.md +0 -33
  48. data/examples/sinatra/anycable +0 -18
  49. data/examples/sinatra/app.rb +0 -52
  50. data/examples/sinatra/assets/app.css +0 -169
  51. data/examples/sinatra/assets/cable.js +0 -584
  52. data/examples/sinatra/assets/reset.css +0 -223
  53. data/examples/sinatra/bin/anycable-go +0 -0
  54. data/examples/sinatra/chat.rb +0 -39
  55. data/examples/sinatra/config.ru +0 -28
  56. data/examples/sinatra/views/index.slim +0 -8
  57. data/examples/sinatra/views/layout.slim +0 -15
  58. data/examples/sinatra/views/login.slim +0 -8
  59. data/examples/sinatra/views/resetcss.slim +0 -224
  60. data/examples/sinatra/views/room.slim +0 -68
  61. data/lib/lite_cable/server/websocket_ext/protocols.rb +0 -45
  62. data/litecable.gemspec +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4640e78d6f9a77cf9257cb0774ff249ec1b5f699
4
- data.tar.gz: a2cc894fc9e355baa79d82afde6682c570ddc21c
2
+ SHA256:
3
+ metadata.gz: 47a04414eade53832c4b900305ca3a034999724c0cabd6aceacb908192a6124f
4
+ data.tar.gz: 24c67d2cacbb5f64b5b7d63293c7fdbe143797d0102b732983fc78028469dfc9
5
5
  SHA512:
6
- metadata.gz: '0588bb0b62119753f79382bfe9955f7db54a693f2625c05426bcf08f131ed8b5b10fdb1e2bd0950545e030530ecfa823383c037747e654b43e7aa650db7187cb'
7
- data.tar.gz: 6365980a8eece62d0d092349ed583afb1a04e749577f994da5da004dfe4576b64c07edc8744680eecda8f9637d726e6c878a0d50cd281c322070adb67c36df37
6
+ metadata.gz: eb63ada090f884f750828b7c116d1066a020c87ab043d929e4ad46b035299c95972acf1d458813a34da797273e0656fc7613977cfef24c6e0765a7a8dece9a6a
7
+ data.tar.gz: 75314e320e2ed5f18e34c4038d467aef14e73f9b0e4fe01f61955369a52ee28e246e62662a94c3e1d1b9f7ea9999049f8d58e5f7af80479fc88a97b91055720e
@@ -1,6 +1,37 @@
1
1
  # Change log
2
2
 
3
- ## master
3
+ ## 0.7.0 (2020-01-07)
4
+
5
+ - Refactor AnyCable integration ([@palkan][])
6
+
7
+ Now you only need to set AnyCable broadcast adapter:
8
+
9
+ ```ruby
10
+ LiteCable.broadcast_adapter = :any_cable
11
+ ```
12
+
13
+ ```sh
14
+ # or via env/config
15
+ LITECABLE_BROADCAST_ADAPTER=any_cable ruby my_app.rb
16
+ ```
17
+
18
+ - Adapterize broadcast adapters ([@palkan][])
19
+
20
+ - Drop Ruby 2.4 support ([palkan][])
21
+
22
+ ## 0.6.0 (2019-04-12) 🚀
23
+
24
+ - Drop Ruby 2.3 support ([@palkan][])
25
+
26
+ ## 0.5.0 (2017-12-20)
27
+
28
+ - Upgrade for AnyCable 0.5.0 ([@palkan][])
29
+
30
+ ## 0.4.1 (2017-02-04)
31
+
32
+ - Use `websocket-ruby` with sub-protocols support ([@palkan][])
33
+
34
+ ## 0.4.0 (2017-01-29)
4
35
 
5
36
  - Initial version. ([@palkan][])
6
37
 
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 palkan
3
+ Copyright (c) 2017-2020 palkan
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- [![Gem Version](https://badge.fury.io/rb/litecable.svg)](https://rubygems.org/gems/litecable) [![Build Status](https://travis-ci.org/anycable/litecable.svg?branch=master)](https://travis-ci.org/anycable/litecable) [![Circle CI](https://circleci.com/gh/anycable/litecable/tree/master.svg?style=svg)](https://circleci.com/gh/anycable/anycable/tree/master)
1
+ [![Gem Version](https://badge.fury.io/rb/litecable.svg)](https://rubygems.org/gems/litecable)
2
+ [![Build](https://github.com/palkan/litecable/workflows/Build/badge.svg)](https://github.com/palkan/litecable/actions)
2
3
 
3
4
  # Lite Cable
4
5
 
@@ -13,27 +14,23 @@ Compatible with [AnyCable](http://anycable.io) (for production usage).
13
14
 
14
15
  ## Examples
15
16
 
16
- - [Sinatra Lite Cable Chat](https://github.com/palkan/litecable/tree/master/examples/sinatra)
17
+ - [Sinatra LiteCable Chat](https://github.com/palkan/litecable/tree/master/examples/sinatra)
18
+
19
+ - [Connecting LiteCable to Hanami](http://gabrielmalakias.com.br/ruby/hanami/iot/2017/05/26/websockets-connecting-litecable-to-hanami.html) by [@GabrielMalakias](https://github.com/GabrielMalakias)
17
20
 
18
21
  ## Installation
19
22
 
20
23
  Add this line to your application's Gemfile:
21
24
 
22
25
  ```ruby
23
- gem 'litecable'
26
+ gem "litecable"
24
27
  ```
25
28
 
26
- And then execute:
27
-
28
- $ bundle
29
-
30
- Or install it yourself as:
31
-
32
- $ gem install litecable
29
+ And run `bundle install`.
33
30
 
34
31
  ## Usage
35
32
 
36
- Please, checkout [Action Cable guides](http://guides.rubyonrails.org/action_cable_overview.html) for general information. Lite Cable aims to be compatible with Action Cable as much as possible without the loss of simplicity and _ligthness_.
33
+ Please, checkout [Action Cable guides](http://guides.rubyonrails.org/action_cable_overview.html) for general information. Lite Cable aims to be compatible with Action Cable as much as possible without the loss of simplicity and _lightness_.
37
34
 
38
35
  You can use Action Cable javascript client without any change (precompiled version can be found [here](https://github.com/palkan/litecable/tree/master/examples/sinatra/assets/cable.js)).
39
36
 
@@ -71,36 +68,42 @@ To use Lite Cable server:
71
68
 
72
69
  ```ruby
73
70
  Rack::Builder.new do
74
- map '/cable' do
71
+ map "/cable" do
75
72
  # You have to specify your app's connection class
76
73
  use LiteCable::Server::Middleware, connection_class: App::Connection
77
- run proc { |_| [200, { 'Content-Type' => 'text/plain' }, ['OK']] }
74
+ run proc { |_| [200, {"Content-Type" => "text/plain"}, ["OK"]] }
78
75
  end
79
76
  end
80
77
  ```
81
78
 
82
79
  ### Using with AnyCable
83
80
 
84
- Lite Cable is AnyCable-compatible out-of-the-box. You should write a simple server script:
81
+ Lite Cable is AnyCable-compatible out-of-the-box:
82
+
83
+ - Set broadcast adapter to AnyCable:
85
84
 
86
85
  ```ruby
87
- #!/usr/bin/env ruby
86
+ LiteCable.broadcast_adapter = :any_cable
87
+ ```
88
88
 
89
- require "my_app"
90
- require "rack"
91
- require "anycable"
89
+ You can also do this via configuration, e.g., env var (`LITECABLE_BROADCAST_ADAPTER=any_cable`) or `broadcast_adapter: any_cable` in a YAML config.
92
90
 
93
- # Turn AnyCable compatibility mode
94
- LiteCable.anycable!
91
+ - Configure connection factory:
95
92
 
96
- Anycable.configure do |config|
97
- config.connection_factory = MyApp::Connection
98
- end
93
+ ```ruby
94
+ AnyCable.connection_factory = MyApp::Connection
95
+ ```
99
96
 
100
- Anycable::Server.start
97
+ Then run AnyCable along with the app:
98
+
99
+ ```sh
100
+ bundle exec anycable
101
+
102
+ # add -r option to load the app if it's not ./config/anycable.rb or ./config/environment.rb
103
+ bundle exec anycable -r ./my_app.rb
101
104
  ```
102
105
 
103
- And then run this script along with your application. See [Sinatra example](https://github.com/palkan/litecable/tree/master/examples/sinatra) for more.
106
+ See [Sinatra example](https://github.com/palkan/litecable/tree/master/examples/sinatra) for more.
104
107
 
105
108
  ### Configuration
106
109
 
@@ -120,9 +123,8 @@ See [config](https://github.com/palkan/litecable/blob/master/lib/lite_cable/conf
120
123
 
121
124
  ## Contributing
122
125
 
123
- Bug reports and pull requests are welcome on GitHub at https://github.com/anycable/litecable.
126
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/palkan/litecable](https://github.com/palkan/litecable).
124
127
 
125
128
  ## License
126
129
 
127
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
128
-
130
+ The gem is available as open source under the terms of the [MIT License](./LICENSE.txt).
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "lite_cable/version"
3
4
  require "lite_cable/internal"
4
5
  require "lite_cable/logging"
@@ -14,6 +15,7 @@ module LiteCable
14
15
  require "lite_cable/channel"
15
16
  require "lite_cable/coders"
16
17
  require "lite_cable/config"
18
+ require "lite_cable/broadcast_adapters"
17
19
  require "lite_cable/anycable"
18
20
 
19
21
  class << self
@@ -22,8 +24,27 @@ module LiteCable
22
24
  end
23
25
 
24
26
  # Broadcast encoded message to the stream
25
- def broadcast(*args)
26
- LiteCable::Server.broadcast(*args)
27
+ def broadcast(stream, message, coder: LiteCable.config.coder)
28
+ broadcast_adapter.broadcast(stream, message, coder: coder)
29
+ end
30
+
31
+ def broadcast_adapter
32
+ return @broadcast_adapter if defined?(@broadcast_adapter)
33
+ self.broadcast_adapter = LiteCable.config.broadcast_adapter.to_sym
34
+ @broadcast_adapter
35
+ end
36
+
37
+ def broadcast_adapter=(adapter)
38
+ if adapter.is_a?(Symbol) || adapter.is_a?(Array)
39
+ adapter = BroadcastAdapters.lookup_adapter(adapter)
40
+ end
41
+
42
+ unless adapter.respond_to?(:broadcast)
43
+ raise ArgumentError, "BroadcastAdapter must implement #broadcast method. " \
44
+ "#{adapter.class} doesn't implement it."
45
+ end
46
+
47
+ @broadcast_adapter = adapter
27
48
  end
28
49
  end
29
50
  end
@@ -1,21 +1,15 @@
1
1
  # frozen_string_literal: true
2
- module LiteCable
2
+
3
+ module LiteCable # :nodoc:
3
4
  # AnyCable extensions
4
5
  module AnyCable
5
- module Broadcasting # :nodoc:
6
- def broadcast(stream, message, coder: nil)
7
- coder ||= LiteCable.config.coder
8
- Anycable.broadcast stream, coder.encode(message)
9
- end
10
- end
11
-
12
6
  module Connection # :nodoc:
13
7
  def self.extended(base)
14
8
  base.prepend InstanceMethods
15
9
  end
16
10
 
17
- def create(socket, **options)
18
- new(socket, **options)
11
+ def call(socket, **options)
12
+ new(socket, options)
19
13
  end
20
14
 
21
15
  module InstanceMethods # :nodoc:
@@ -29,6 +23,7 @@ module LiteCable
29
23
  @request ||= Rack::Request.new(socket.env)
30
24
  end
31
25
 
26
+ # rubocop: disable Metrics/MethodLength
32
27
  def handle_channel_command(identifier, command, data)
33
28
  channel = subscriptions.add(identifier, false)
34
29
  case command
@@ -50,13 +45,27 @@ module LiteCable
50
45
  close
51
46
  false
52
47
  end
48
+ # rubocop: enable Metrics/MethodLength
53
49
  end
54
50
  end
55
51
  end
56
52
 
57
- # Patch Lite Cable with AnyCable functionality
53
+ # Patch Lite Cable with AnyCable functionality
58
54
  def self.anycable!
59
55
  LiteCable::Connection::Base.extend LiteCable::AnyCable::Connection
60
- LiteCable.singleton_class.prepend LiteCable::AnyCable::Broadcasting
56
+ end
57
+ end
58
+
59
+ if defined?(AnyCable)
60
+ AnyCable.configure_server do
61
+ # Make sure broadcast adapter is valid
62
+ require "lite_cable/broadcast_adapters/any_cable"
63
+ unless LiteCable::BroadcastAdapters::AnyCable === LiteCable.broadcast_adapter
64
+ raise "You should use :any_cable broadcast adapter (current: #{LiteCable.broadcast_adapter.class}). " \
65
+ "Set it via LITECABLE_BROADCAST_ADAPTER=any_cable or in the code/YML."
66
+ end
67
+
68
+ # Turn AnyCable compatibility mode for anycable RPC server automatically
69
+ LiteCable.anycable!
61
70
  end
62
71
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lite_cable/broadcast_adapters/base"
4
+
5
+ module LiteCable
6
+ module BroadcastAdapters # :nodoc:
7
+ module_function
8
+
9
+ # rubocop: disable Metrics/AbcSize, Metrics/MethodLength
10
+ def lookup_adapter(args)
11
+ adapter, options = Array(args)
12
+ path_to_adapter = "lite_cable/broadcast_adapters/#{adapter}"
13
+ adapter_class_name = adapter.to_s.split("_").map(&:capitalize).join
14
+
15
+ unless BroadcastAdapters.const_defined?(adapter_class_name, false)
16
+ begin
17
+ require path_to_adapter
18
+ rescue LoadError => e
19
+ # We couldn't require the adapter itself.
20
+ if e.path == path_to_adapter
21
+ raise e.class, "Couldn't load the '#{adapter}' broadcast adapter for LiteCable",
22
+ e.backtrace
23
+ # Bubbled up from the adapter require.
24
+ else
25
+ raise e.class, "Error loading the '#{adapter}' broadcast adapter for LiteCable",
26
+ e.backtrace
27
+ end
28
+ end
29
+ end
30
+
31
+ BroadcastAdapters.const_get(adapter_class_name, false).new(**(options || {}))
32
+ end
33
+ # rubocop: enable Metrics/AbcSize, Metrics/MethodLength
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiteCable
4
+ module BroadcastAdapters
5
+ class AnyCable < Base
6
+ def broadcast(stream, message, coder:)
7
+ ::AnyCable.broadcast stream, coder.encode(message)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # frozen_string_literal: true
4
+
5
+ module LiteCable
6
+ module BroadcastAdapters
7
+ class Base
8
+ def initialize(**options)
9
+ @options = options
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :options
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LiteCable
4
+ module BroadcastAdapters
5
+ class Memory < Base
6
+ def broadcast(stream, message, coder:)
7
+ Server.subscribers_map.broadcast stream, message, coder
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Channel # :nodoc:
4
5
  require "lite_cable/channel/registry"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  # rubocop:disable Metrics/LineLength
4
5
  module Channel
@@ -128,6 +129,7 @@ module LiteCable
128
129
  action = extract_action(data)
129
130
 
130
131
  raise UnproccessableActionError unless processable_action?(action)
132
+
131
133
  log(:debug) { log_fmt("Perform action #{action}(#{data})") }
132
134
  dispatch_action(action, data)
133
135
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Channel
4
5
  # Stores channels identifiers and corresponding classes.
@@ -10,6 +11,7 @@ module LiteCable
10
11
  class << self
11
12
  def add(id, channel_class)
12
13
  raise AlreadyRegisteredError if find(id)
14
+
13
15
  channels[id] = channel_class
14
16
  end
15
17
 
@@ -20,6 +22,7 @@ module LiteCable
20
22
  def find!(id)
21
23
  channel_class = find(id)
22
24
  raise UnknownChannelError unless channel_class
25
+
23
26
  channel_class
24
27
  end
25
28
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  # rubocop:disable Metrics/LineLength
4
5
  module Channel
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Coders # :nodoc:
4
5
  require "lite_cable/coders/raw"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "json"
3
4
 
4
5
  module LiteCable
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Coders
4
5
  # No-op coder
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
- require "anyway"
3
- require 'logger'
2
+
3
+ require "anyway_config"
4
+ require "logger"
4
5
 
5
6
  module LiteCable
6
- # Anycable configuration
7
+ # AnyCable configuration
7
8
  class Config < Anyway::Config
8
9
  require "lite_cable/coders/json"
9
10
  require "lite_cable/coders/raw"
@@ -11,8 +12,9 @@ module LiteCable
11
12
  config_name :litecable
12
13
 
13
14
  attr_config :logger,
14
- coder: Coders::JSON,
15
- identifier_coder: Coders::Raw,
16
- log_level: Logger::INFO
15
+ coder: Coders::JSON,
16
+ broadcast_adapter: :memory,
17
+ identifier_coder: Coders::Raw,
18
+ log_level: Logger::INFO
17
19
  end
18
20
  end