anycable-rack-server 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61ac3aaa885caabfc4e6761dc77f3c8f792d966c13dc598b6c100c58c160c334
4
- data.tar.gz: f1317d8d0b6d38266bd8c9f6866c2d4e1e7e24225b758d2e8c06ef6176251cc4
3
+ metadata.gz: ac33d07a88c1d94d982a7068f7636fc74013dd13e18a08ba29019c1b6e90bdb1
4
+ data.tar.gz: c655148349178d792f6609202762845189669053a14f89aa4a5f0c6efae67ff6
5
5
  SHA512:
6
- metadata.gz: 577a63b90c45172860302d22893db7828f748a80dc3fe8443a819c78b4c91eed10d61fecf70e6d8aeb00f50daa667cb31d9dcfe661d73e20ae65027ebbdb6a87
7
- data.tar.gz: 4d1c8fa0810a6ea93ebebcbbc868e0713e648cebfe1af0d6761205b396b0a44cc2c79b716f50d740314c8d8faa382f873124e60275430563faa8460e019754b6
6
+ metadata.gz: 4ecbcb8c30cfa5e4b79948bc37c06405068d80bb192f53d98901d7177110da4822a20eff456a12fb7da5e7a3c3f8757ad219acb0befb2d7cd705288b3b1a3b12
7
+ data.tar.gz: a687c493138b5e0c7429e6a58c1b99ea4388a8b988988f0cc4bcab656db4789494e6b0fb05d59936794dfb6a99dc1b4868b90f82c551c049a2c33cf1c9c78d98
@@ -32,7 +32,7 @@ module AnyCable
32
32
  if data["stream"]
33
33
  hub.broadcast(data["stream"], data["data"], coder)
34
34
  elsif data["command"] == "disconnect"
35
- hub.disconnect(data["payload"]["identifier"], data["payload"]["reconnect"])
35
+ hub.disconnect(data["payload"]["identifier"], data["payload"]["reconnect"], coder)
36
36
  end
37
37
  end
38
38
  end
@@ -5,7 +5,7 @@ require "json"
5
5
  module AnyCable
6
6
  module Rack
7
7
  module Coders
8
- module JSON # :nodoc:
8
+ module Json # :nodoc:
9
9
  class << self
10
10
  def decode(json_str)
11
11
  ::JSON.parse(json_str)
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ gem "msgpack", "~> 1.4"
4
+ require "msgpack"
5
+
6
+ module AnyCable
7
+ module Rack
8
+ module Coders
9
+ module Msgpack # :nodoc:
10
+ class << self
11
+ def decode(bin)
12
+ MessagePack.unpack(bin)
13
+ end
14
+
15
+ def encode(ruby_obj)
16
+ BinaryFrame.new(MessagePack.pack(ruby_obj))
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -12,6 +12,7 @@ module AnyCable
12
12
 
13
13
  attr_config mount_path: "/cable",
14
14
  headers: DEFAULT_HEADERS,
15
+ coder: :json,
15
16
  rpc_addr: "localhost:50051",
16
17
  rpc_client_pool_size: 5,
17
18
  rpc_client_timeout: 5,
@@ -67,7 +67,8 @@ module AnyCable
67
67
  private
68
68
 
69
69
  def transmit(cable_message)
70
- socket.transmit(encode(cable_message))
70
+ encoded = encode(cable_message)
71
+ socket.transmit(encoded)
71
72
  end
72
73
 
73
74
  def close
@@ -133,7 +134,7 @@ module AnyCable
133
134
  end
134
135
 
135
136
  def process_command(response, identifier)
136
- response.transmissions.each { |transmission| transmit(decode(transmission)) }
137
+ response.transmissions.each { |transmission| transmit(decode_transmission(transmission)) }
137
138
  hub.remove_channel(socket, identifier) if response.stop_streams
138
139
  response.streams.each { |stream| hub.add_subscriber(stream, socket, identifier) }
139
140
  response.stopped_streams.each { |stream| hub.remove_subscriber(stream, socket, identifier) }
@@ -145,7 +146,7 @@ module AnyCable
145
146
  end
146
147
 
147
148
  def process_open(response)
148
- response.transmissions&.each { |transmission| transmit(decode(transmission)) }
149
+ response.transmissions&.each { |transmission| transmit(decode_transmission(transmission)) }
149
150
  if response.status == :SUCCESS
150
151
  @_identifiers = response.identifiers
151
152
  @_cstate = response.env.cstate&.to_h || {}
@@ -181,6 +182,10 @@ module AnyCable
181
182
  coder.encode(cable_message)
182
183
  end
183
184
 
185
+ def decode_transmission(json_message)
186
+ JSON.parse(json_message)
187
+ end
188
+
184
189
  def decode(websocket_message)
185
190
  coder.decode(websocket_message)
186
191
  end
@@ -71,7 +71,7 @@ module AnyCable
71
71
  end
72
72
 
73
73
  list.each do |(channel_id, sockets)|
74
- decoded = coder.decode(message)
74
+ decoded = JSON.parse(message)
75
75
  cmessage = channel_message(channel_id, decoded, coder)
76
76
  sockets.each { |socket| socket.transmit(cmessage) }
77
77
  end
@@ -81,14 +81,14 @@ module AnyCable
81
81
  sockets.each_key { |socket| socket.transmit(message) }
82
82
  end
83
83
 
84
- def disconnect(identifier, reconnect)
84
+ def disconnect(identifier, reconnect, coder)
85
85
  sockets = @sync.synchronize do
86
86
  return unless @streams[INTERNAL_STREAM].key?(identifier)
87
87
 
88
88
  @streams[INTERNAL_STREAM][identifier].to_a
89
89
  end
90
90
 
91
- msg = disconnect_message("remote", reconnect)
91
+ msg = disconnect_message("remote", reconnect, coder)
92
92
 
93
93
  sockets.each do |socket|
94
94
  socket.transmit(msg)
@@ -115,9 +115,8 @@ module AnyCable
115
115
  coder.encode(identifier: channel_id, message: message)
116
116
  end
117
117
 
118
- # FIXME: coder support?
119
- def disconnect_message(reason, reconnect)
120
- {type: :disconnect, reason: reason, reconnect: reconnect}.to_json
118
+ def disconnect_message(reason, reconnect, coder)
119
+ coder.encode({type: :disconnect, reason: reason, reconnect: reconnect})
121
120
  end
122
121
  end
123
122
  end
@@ -9,7 +9,7 @@ require "anycable/rack/socket"
9
9
  module AnyCable
10
10
  module Rack
11
11
  class Middleware # :nodoc:
12
- PROTOCOLS = ["actioncable-v1-json", "actioncable-unsupported"].freeze
12
+ PROTOCOLS = ["actioncable-v1-json", "actioncable-v1-msgpack", "actioncable-unsupported"].freeze
13
13
  attr_reader :pinger,
14
14
  :hub,
15
15
  :coder,
@@ -8,7 +8,10 @@ module AnyCable
8
8
  class Pinger
9
9
  INTERVAL = 3
10
10
 
11
- def initialize
11
+ attr_reader :coder
12
+
13
+ def initialize(coder)
14
+ @coder = coder
12
15
  @_sockets = []
13
16
  @_stopped = false
14
17
  end
@@ -45,7 +48,7 @@ module AnyCable
45
48
  private
46
49
 
47
50
  def ping_message(time)
48
- {type: :ping, message: time}.to_json
51
+ coder.encode({type: :ping, message: time})
49
52
  end
50
53
  end
51
54
  end
@@ -8,7 +8,6 @@ require "anycable/rack/errors"
8
8
  require "anycable/rack/middleware"
9
9
  require "anycable/rack/logging"
10
10
  require "anycable/rack/broadcast_subscribers/base_subscriber"
11
- require "anycable/rack/coders/json"
12
11
 
13
12
  module AnyCable # :nodoc: all
14
13
  module Rack
@@ -28,9 +27,8 @@ module AnyCable # :nodoc: all
28
27
  def initialize(config: AnyCable::Rack.config)
29
28
  @config = config
30
29
  @hub = Hub.new
31
- @pinger = Pinger.new
32
- # TODO: Support other coders
33
- @coder = Coders::JSON
30
+ @coder = resolve_coder(config.coder)
31
+ @pinger = Pinger.new(coder)
34
32
 
35
33
  @broadcast = resolve_broadcast_adapter
36
34
  @rpc_client = RPC::Client.new(
@@ -112,6 +110,11 @@ module AnyCable # :nodoc: all
112
110
  raise ArgumentError, "Unsupported broadcast adatper: #{adapter}. AnyCable Rack server only supports: redis, http"
113
111
  end
114
112
  end
113
+
114
+ def resolve_coder(name)
115
+ require "anycable/rack/coders/#{name}"
116
+ AnyCable::Rack::Coders.const_get(name.capitalize)
117
+ end
115
118
  end
116
119
  end
117
120
  end
@@ -4,6 +4,17 @@ require "anycable/rack/logging"
4
4
 
5
5
  module AnyCable
6
6
  module Rack
7
+ # Wrapper for outgoing data used to correctly set the WS frame type
8
+ class BinaryFrame
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def to_s
14
+ @data.to_s
15
+ end
16
+ end
17
+
7
18
  # Socket wrapper
8
19
  class Socket
9
20
  include Logging
@@ -22,7 +33,9 @@ module AnyCable
22
33
  @_active = true
23
34
  end
24
35
 
25
- def transmit(data, type: :text)
36
+ def transmit(data, type: nil)
37
+ # p "DATA: #{data.class} — #{data.to_s}"
38
+ type ||= data.is_a?(BinaryFrame) ? :binary : :text
26
39
  frame = WebSocket::Frame::Outgoing::Server.new(
27
40
  version: version,
28
41
  data: data,
@@ -144,7 +157,7 @@ module AnyCable
144
157
  end
145
158
  end
146
159
  rescue Exception => e # rubocop:disable Lint/RescueException
147
- log(:error, "Socket frame error: #{e}")
160
+ log(:error, "Socket frame error: #{e}\n #{e.backtrace.take(4).join("\n")}")
148
161
  nil # client disconnected or timed out
149
162
  end
150
163
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module AnyCable
4
4
  module Rack
5
- VERSION = "0.3.0"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anycable-rack-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yulia Oletskaya
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-05-12 00:00:00.000000000 Z
12
+ date: 2021-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: anyway_config
@@ -170,6 +170,7 @@ files:
170
170
  - lib/anycable/rack/broadcast_subscribers/http_subscriber.rb
171
171
  - lib/anycable/rack/broadcast_subscribers/redis_subscriber.rb
172
172
  - lib/anycable/rack/coders/json.rb
173
+ - lib/anycable/rack/coders/msgpack.rb
173
174
  - lib/anycable/rack/config.rb
174
175
  - lib/anycable/rack/connection.rb
175
176
  - lib/anycable/rack/errors.rb