anycable-rack-server 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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