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
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Connection # :nodoc:
4
5
  require "lite_cable/connection/authorization"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Connection
4
5
  class UnauthorizedError < StandardError; end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  # rubocop:disable Metrics/LineLength
4
5
  module Connection
@@ -79,6 +80,7 @@ module LiteCable
79
80
 
80
81
  def transmit(cable_message)
81
82
  return if disconnected?
83
+
82
84
  socket.transmit encode(cable_message)
83
85
  end
84
86
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "set"
3
4
 
4
5
  module LiteCable
@@ -13,6 +14,7 @@ module LiteCable
13
14
  define_method(identifier) do
14
15
  return instance_variable_get(:"@#{identifier}") if
15
16
  instance_variable_defined?(:"@#{identifier}")
17
+
16
18
  fetch_identifier(identifier.to_s)
17
19
  end
18
20
  end
@@ -66,6 +68,7 @@ module LiteCable
66
68
  identifiers.each_with_object({}) do |id, acc|
67
69
  obj = instance_variable_get("@#{id}")
68
70
  next unless obj
71
+
69
72
  acc[id.to_s] = LiteCable.config.identifier_coder.encode(obj)
70
73
  end
71
74
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Connection
4
5
  # Manage the connection streams
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Connection
4
5
  # Manage the connection channels and route messages
@@ -52,11 +53,11 @@ module LiteCable
52
53
  def execute_command(data)
53
54
  command = data.delete("command")
54
55
  case command
55
- when "subscribe" then add(data["identifier"])
56
+ when "subscribe" then add(data["identifier"])
56
57
  when "unsubscribe" then remove(data["identifier"])
57
- when "message" then perform_action(data["identifier"], data["data"])
58
+ when "message" then perform_action(data["identifier"], data["data"])
58
59
  else
59
- raise UnknownCommandError
60
+ raise UnknownCommandError, "Command not found #{command}"
60
61
  end
61
62
  end
62
63
 
@@ -67,6 +68,7 @@ module LiteCable
67
68
  def find!(identifier)
68
69
  channel = find(identifier)
69
70
  raise ChannelNotFoundError unless channel
71
+
70
72
  channel
71
73
  end
72
74
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  INTERNAL = {
4
5
  message_types: {
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'logger'
2
+
3
+ require "logger"
3
4
 
4
5
  module LiteCable
5
6
  module Logging # :nodoc:
@@ -22,6 +23,7 @@ module LiteCable
22
23
 
23
24
  def log(level, message = nil)
24
25
  return unless LiteCable::Logging.logger
26
+
25
27
  LiteCable::Logging.logger.send(level, PREFIX) { message || yield }
26
28
  end
27
29
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  # Rack middleware to hijack sockets.
4
5
  #
@@ -14,12 +15,6 @@ module LiteCable
14
15
 
15
16
  class << self
16
17
  attr_accessor :subscribers_map
17
-
18
- # Broadcast encoded message to the stream
19
- def broadcast(stream, message, coder: nil)
20
- coder ||= LiteCable.config.coder
21
- subscribers_map.broadcast stream, message, coder
22
- end
23
18
  end
24
19
 
25
20
  self.subscribers_map = SubscribersMap.new
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Server
4
5
  module ClientSocket # :nodoc:
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Server
4
5
  module ClientSocket
5
6
  # Wrapper over web socket
6
- # rubocop:disable Metrics/ClassLength
7
7
  class Base
8
8
  include Logging
9
9
  include Subscriptions
@@ -17,10 +17,10 @@ module LiteCable
17
17
  @version = version
18
18
  @active = true
19
19
 
20
- @open_handlers = []
20
+ @open_handlers = []
21
21
  @message_handlers = []
22
- @close_handlers = []
23
- @error_handlers = []
22
+ @close_handlers = []
23
+ @error_handlers = []
24
24
 
25
25
  @close_on_error = true
26
26
  end
@@ -61,6 +61,7 @@ module LiteCable
61
61
  @error_handlers << block
62
62
  end
63
63
 
64
+ # rubocop: disable Metrics/MethodLength
64
65
  def listen
65
66
  keepalive
66
67
  Thread.new do
@@ -69,13 +70,11 @@ module LiteCable
69
70
  @open_handlers.each(&:call)
70
71
  each_frame do |data|
71
72
  @message_handlers.each do |h|
72
- begin
73
- h.call(data)
74
- rescue => e
75
- log(:error, "Socket receive failed: #{e}")
76
- @error_handlers.each { |eh| eh.call(e, data) }
77
- close if close_on_error
78
- end
73
+ h.call(data)
74
+ rescue => e # rubocop: disable Style/RescueStandardError
75
+ log(:error, "Socket receive failed: #{e}")
76
+ @error_handlers.each { |eh| eh.call(e, data) }
77
+ close if close_on_error
79
78
  end
80
79
  end
81
80
  ensure
@@ -83,6 +82,7 @@ module LiteCable
83
82
  end
84
83
  end
85
84
  end
85
+ # rubocop: enable Metrics/MethodLength
86
86
 
87
87
  def close
88
88
  return unless @active
@@ -113,6 +113,8 @@ module LiteCable
113
113
  frame = WebSocket::Frame::Outgoing::Server.new(version: version, type: :close, code: 1000)
114
114
  @socket.write(frame.to_s) if frame.supported?
115
115
  @socket.close
116
+ rescue IOError, Errno::EPIPE, Errno::ETIMEDOUT # rubocop:disable Lint/HandleExceptions
117
+ # already closed
116
118
  end
117
119
 
118
120
  def keepalive
@@ -129,22 +131,15 @@ module LiteCable
129
131
  end
130
132
  end
131
133
 
132
- # rubocop:disable Metrics/AbcSize
133
- # rubocop:disable Metrics/CyclomaticComplexity
134
- # rubocop:disable Metrics/PerceivedComplexity
135
- # rubocop:disable Metrics/MethodLength
136
134
  def each_frame
137
135
  framebuffer = WebSocket::Frame::Incoming::Server.new(version: version)
138
136
 
139
137
  while IO.select([socket])
140
- if socket.respond_to?(:recvfrom)
141
- data, _addrinfo = socket.recvfrom(2000)
142
- else
143
- data, _addrinfo = socket.readpartial(2000), socket.peeraddr
144
- end
138
+ data = socket.respond_to?(:recv) ? socket.recv(2000) : socket.readpartial(2000)
145
139
  break if data.empty?
140
+
146
141
  framebuffer << data
147
- while frame = framebuffer.next
142
+ while frame = framebuffer.next # rubocop:disable Lint/AssignmentInCondition
148
143
  case frame.type
149
144
  when :close
150
145
  return
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Server
4
5
  module ClientSocket
@@ -6,12 +7,12 @@ module LiteCable
6
7
  module Subscriptions
7
8
  def subscribe(channel, broadcasting)
8
9
  LiteCable::Server.subscribers_map
9
- .add_subscriber(broadcasting, self, channel)
10
+ .add_subscriber(broadcasting, self, channel)
10
11
  end
11
12
 
12
13
  def unsubscribe(channel, broadcasting)
13
14
  LiteCable::Server.subscribers_map
14
- .remove_subscriber(broadcasting, self, channel)
15
+ .remove_subscriber(broadcasting, self, channel)
15
16
  end
16
17
 
17
18
  def unsubscribe_from_all(channel)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Server
4
5
  # Sends pings to sockets
@@ -22,6 +23,7 @@ module LiteCable
22
23
  @stopped = true
23
24
  end
24
25
 
26
+ # rubocop: disable Metrics/MethodLength
25
27
  def run
26
28
  Thread.new do
27
29
  Thread.current.abort_on_exception = true
@@ -39,11 +41,12 @@ module LiteCable
39
41
  end
40
42
  end
41
43
  end
44
+ # rubocop: enable Metrics/MethodLength
42
45
 
43
46
  private
44
47
 
45
48
  def ping_message(time)
46
- { type: LiteCable::INTERNAL[:message_types][:ping], message: time }.to_json
49
+ {type: LiteCable::INTERNAL[:message_types][:ping], message: time}.to_json
47
50
  end
48
51
  end
49
52
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Server
4
- require "lite_cable/server/websocket_ext/protocols"
5
5
  # Rack middleware to hijack the socket
6
6
  class Middleware
7
7
  class HijackNotAvailable < RuntimeError; end
@@ -12,15 +12,15 @@ module LiteCable
12
12
  end
13
13
 
14
14
  def call(env)
15
- return [404, { 'Content-Type' => 'text/plain' }, ['Not Found']] unless
16
- env["HTTP_UPGRADE"] == 'websocket'
15
+ return [404, {"Content-Type" => "text/plain"}, ["Not Found"]] unless
16
+ env["HTTP_UPGRADE"] == "websocket"
17
17
 
18
- raise HijackNotAvailable unless env['rack.hijack']
18
+ raise HijackNotAvailable unless env["rack.hijack"]
19
19
 
20
- env['rack.hijack'].call
20
+ env["rack.hijack"].call
21
21
  handshake = send_handshake(env)
22
22
 
23
- socket = ClientSocket::Base.new env, env['rack.hijack_io'], handshake.version
23
+ socket = ClientSocket::Base.new env, env["rack.hijack_io"], handshake.version
24
24
  init_connection socket
25
25
  init_heartbeat socket
26
26
  socket.listen
@@ -30,11 +30,12 @@ module LiteCable
30
30
  private
31
31
 
32
32
  def send_handshake(env)
33
- handshake = WebSocket::Handshake::Server.new
34
- handshake.from_rack env
35
- handshake.protocols LiteCable::INTERNAL[:protocols]
33
+ handshake = WebSocket::Handshake::Server.new(
34
+ protocols: LiteCable::INTERNAL[:protocols]
35
+ )
36
36
 
37
- env['rack.hijack_io'].write handshake.to_s
37
+ handshake.from_rack env
38
+ env["rack.hijack_io"].write handshake.to_s
38
39
  handshake
39
40
  end
40
41
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
4
  module Server
4
5
  # From https://github.com/rails/rails/blob/v5.0.1/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb
@@ -31,6 +32,7 @@ module LiteCable
31
32
  def remove_socket(socket, channel)
32
33
  list = @sync.synchronize do
33
34
  return unless @sockets.key?(socket)
35
+
34
36
  @sockets[socket].dup
35
37
  end
36
38
 
@@ -42,6 +44,7 @@ module LiteCable
42
44
  def broadcast(stream, message, coder)
43
45
  list = @sync.synchronize do
44
46
  return unless @streams.key?(stream)
47
+
45
48
  @streams[stream].to_a
46
49
  end
47
50
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module LiteCable
3
- VERSION = "0.4.0"
4
+ VERSION = "0.7.0"
4
5
  end
@@ -1,2 +1,3 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "lite_cable"
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: litecable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-29 00:00:00.000000000 Z
11
+ date: 2020-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.5.0
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.5.0
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.2.0
47
+ version: 1.2.4
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.2.0
54
+ version: 1.2.4
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: websocket-client-simple
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,54 +72,54 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.0.0
75
+ version: '1.1'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.0.0
82
+ version: '1.1'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: puma
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 3.6.0
89
+ version: '3.6'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 3.6.0
96
+ version: '3.6'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bundler
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '1.13'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.13'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rake
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - "~>"
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '10.0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - "~>"
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '10.0'
125
125
  - !ruby/object:Gem::Dependency
@@ -172,36 +172,15 @@ executables: []
172
172
  extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
- - ".gitignore"
176
- - ".rspec"
177
- - ".rubocop.yml"
178
- - ".travis.yml"
179
175
  - CHANGELOG.md
180
- - Gemfile
181
176
  - LICENSE.txt
182
177
  - README.md
183
- - Rakefile
184
- - bin/console
185
- - bin/setup
186
- - circle.yml
187
- - examples/sinatra/Gemfile
188
- - examples/sinatra/Procfile
189
- - examples/sinatra/README.md
190
- - examples/sinatra/anycable
191
- - examples/sinatra/app.rb
192
- - examples/sinatra/assets/app.css
193
- - examples/sinatra/assets/cable.js
194
- - examples/sinatra/assets/reset.css
195
- - examples/sinatra/bin/anycable-go
196
- - examples/sinatra/chat.rb
197
- - examples/sinatra/config.ru
198
- - examples/sinatra/views/index.slim
199
- - examples/sinatra/views/layout.slim
200
- - examples/sinatra/views/login.slim
201
- - examples/sinatra/views/resetcss.slim
202
- - examples/sinatra/views/room.slim
203
178
  - lib/lite_cable.rb
204
179
  - lib/lite_cable/anycable.rb
180
+ - lib/lite_cable/broadcast_adapters.rb
181
+ - lib/lite_cable/broadcast_adapters/any_cable.rb
182
+ - lib/lite_cable/broadcast_adapters/base.rb
183
+ - lib/lite_cable/broadcast_adapters/memory.rb
205
184
  - lib/lite_cable/channel.rb
206
185
  - lib/lite_cable/channel/base.rb
207
186
  - lib/lite_cable/channel/registry.rb
@@ -225,14 +204,17 @@ files:
225
204
  - lib/lite_cable/server/heart_beat.rb
226
205
  - lib/lite_cable/server/middleware.rb
227
206
  - lib/lite_cable/server/subscribers_map.rb
228
- - lib/lite_cable/server/websocket_ext/protocols.rb
229
207
  - lib/lite_cable/version.rb
230
208
  - lib/litecable.rb
231
- - litecable.gemspec
232
- homepage: https://github.com/anycable/litecable
209
+ homepage: https://github.com/palkan/litecable
233
210
  licenses:
234
211
  - MIT
235
- metadata: {}
212
+ metadata:
213
+ bug_tracker_uri: http://github.com/palkan/litecable/issues
214
+ changelog_uri: https://github.com/palkan/litecable/blob/master/CHANGELOG.md
215
+ documentation_uri: http://github.com/palkan/litecable
216
+ homepage_uri: http://github.com/palkan/litecable
217
+ source_code_uri: http://github.com/palkan/litecable
236
218
  post_install_message:
237
219
  rdoc_options: []
238
220
  require_paths:
@@ -241,15 +223,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
241
223
  requirements:
242
224
  - - ">="
243
225
  - !ruby/object:Gem::Version
244
- version: '0'
226
+ version: 2.5.0
245
227
  required_rubygems_version: !ruby/object:Gem::Requirement
246
228
  requirements:
247
229
  - - ">="
248
230
  - !ruby/object:Gem::Version
249
231
  version: '0'
250
232
  requirements: []
251
- rubyforge_project:
252
- rubygems_version: 2.6.4
233
+ rubygems_version: 3.0.6
253
234
  signing_key:
254
235
  specification_version: 4
255
236
  summary: Fat-free ActionCable implementation