async-cable 0.1.0 → 0.3.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/cable/middleware.rb +10 -4
- data/lib/async/cable/socket.rb +6 -1
- data/lib/async/cable/version.rb +2 -1
- data/readme.md +8 -0
- data/releases.md +8 -0
- data.tar.gz.sig +0 -0
- metadata +4 -11
- metadata.gz.sig +0 -0
- data/lib/action_cable/subscription_adapters/async_cable_redis.rb +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9aa3fe6a825d58f713ffd71b32b26bd034de7f3175ee6b9505e4f53433f6999
|
4
|
+
data.tar.gz: 5bea7df4792f6f0bf2ed0847437ac13f23972de50b443854f597b4f9b8b6defa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2291b430d4dbfd1072d8dadb1643857e71e84ef749dd08f6bb97168cdb842af6edf6da703d41acc370d9899e0130fffd068ac568a0d5bf269306746e3aeefe11
|
7
|
+
data.tar.gz: aa8346b8289d1dbe14e606631506ee5a2801cef846a67b13cb0e092806f0da1c6cdf980358b43163c3b2a614fea71bd5f8363383051f741ff39a03794a0e5ff7
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# Released under the MIT License.
|
3
4
|
# Copyright, 2024, by Samuel Williams.
|
4
5
|
|
@@ -10,8 +11,9 @@ require_relative "socket"
|
|
10
11
|
module Async
|
11
12
|
module Cable
|
12
13
|
class Middleware
|
13
|
-
def initialize(app, server: ActionCable.server)
|
14
|
+
def initialize(app, path: "/cable", server: ActionCable.server)
|
14
15
|
@app = app
|
16
|
+
@path = path
|
15
17
|
@server = server
|
16
18
|
@coder = ActiveSupport::JSON
|
17
19
|
@protocols = ::ActionCable::INTERNAL[:protocols]
|
@@ -19,8 +21,12 @@ module Async
|
|
19
21
|
|
20
22
|
attr :server
|
21
23
|
|
24
|
+
def valid_path?(env)
|
25
|
+
env["PATH_INFO"] == @path
|
26
|
+
end
|
27
|
+
|
22
28
|
def call(env)
|
23
|
-
if Async::WebSocket::Adapters::Rack.websocket?(env) and allow_request_origin?(env)
|
29
|
+
if valid_path?(env) and Async::WebSocket::Adapters::Rack.websocket?(env) and allow_request_origin?(env)
|
24
30
|
Async::WebSocket::Adapters::Rack.open(env, protocols: @protocols) do |websocket|
|
25
31
|
handle_incoming_websocket(env, websocket)
|
26
32
|
end
|
@@ -42,13 +48,13 @@ module Async
|
|
42
48
|
socket_task = socket.run
|
43
49
|
|
44
50
|
while message = websocket.read
|
45
|
-
Console.debug(self, "Received cable data:", message.buffer)
|
51
|
+
# Console.debug(self, "Received cable data:", message.buffer)
|
46
52
|
connection.handle_incoming(@coder.decode(message.buffer))
|
47
53
|
end
|
48
54
|
rescue Protocol::WebSocket::ClosedError, EOFError
|
49
55
|
# This is a normal disconnection.
|
50
56
|
rescue => error
|
51
|
-
Console.warn(self, error)
|
57
|
+
Console.warn(self, "Abnormal client failure!", error)
|
52
58
|
ensure
|
53
59
|
if connection
|
54
60
|
@server.remove_connection(connection)
|
data/lib/async/cable/socket.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# Released under the MIT License.
|
3
4
|
# Copyright, 2024, by Samuel Williams.
|
4
5
|
|
@@ -33,12 +34,16 @@ module Async::Cable
|
|
33
34
|
def run(parent: Async::Task.current)
|
34
35
|
parent.async do
|
35
36
|
while buffer = @output.pop
|
37
|
+
# Console.debug(self, "Sending cable data:", buffer, flush: @output.empty?)
|
36
38
|
@websocket.send_text(buffer)
|
37
39
|
@websocket.flush if @output.empty?
|
38
40
|
end
|
39
41
|
rescue => error
|
42
|
+
Console.error(self, "Error while sending cable data:", error)
|
40
43
|
ensure
|
41
|
-
@websocket.
|
44
|
+
unless @websocket.closed?
|
45
|
+
@websocket.close_write(error)
|
46
|
+
end
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
data/lib/async/cable/version.rb
CHANGED
data/readme.md
CHANGED
@@ -14,6 +14,14 @@ Please see the [project documentation](https://socketry.github.io/async-cable/)
|
|
14
14
|
|
15
15
|
Please see the [project releases](https://socketry.github.io/async-cable/releases/index) for all releases.
|
16
16
|
|
17
|
+
### v0.3.0
|
18
|
+
|
19
|
+
- Filter requests based on path - don't eat all inbound WebSocket connections.
|
20
|
+
|
21
|
+
### v0.2.0
|
22
|
+
|
23
|
+
- Don't close the WebSocket if it is already closed.
|
24
|
+
|
17
25
|
### v0.1.0
|
18
26
|
|
19
27
|
- Initial implementation.
|
data/releases.md
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-cable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain:
|
11
10
|
- |
|
@@ -37,7 +36,7 @@ cert_chain:
|
|
37
36
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
38
37
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
39
38
|
-----END CERTIFICATE-----
|
40
|
-
date:
|
39
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
41
40
|
dependencies:
|
42
41
|
- !ruby/object:Gem::Dependency
|
43
42
|
name: actioncable-next
|
@@ -81,13 +80,10 @@ dependencies:
|
|
81
80
|
- - ">="
|
82
81
|
- !ruby/object:Gem::Version
|
83
82
|
version: '0'
|
84
|
-
description:
|
85
|
-
email:
|
86
83
|
executables: []
|
87
84
|
extensions: []
|
88
85
|
extra_rdoc_files: []
|
89
86
|
files:
|
90
|
-
- lib/action_cable/subscription_adapters/async_cable_redis.rb
|
91
87
|
- lib/async/cable.rb
|
92
88
|
- lib/async/cable/middleware.rb
|
93
89
|
- lib/async/cable/railtie.rb
|
@@ -96,13 +92,11 @@ files:
|
|
96
92
|
- license.md
|
97
93
|
- readme.md
|
98
94
|
- releases.md
|
99
|
-
homepage:
|
100
95
|
licenses:
|
101
96
|
- MIT
|
102
97
|
metadata:
|
103
98
|
documentation_uri: https://socketry.github.io/async-cable/
|
104
99
|
source_code_uri: https://github.com/socketry/async-cable
|
105
|
-
post_install_message:
|
106
100
|
rdoc_options: []
|
107
101
|
require_paths:
|
108
102
|
- lib
|
@@ -110,15 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
104
|
requirements:
|
111
105
|
- - ">="
|
112
106
|
- !ruby/object:Gem::Version
|
113
|
-
version: '3.
|
107
|
+
version: '3.2'
|
114
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
109
|
requirements:
|
116
110
|
- - ">="
|
117
111
|
- !ruby/object:Gem::Version
|
118
112
|
version: '0'
|
119
113
|
requirements: []
|
120
|
-
rubygems_version: 3.
|
121
|
-
signing_key:
|
114
|
+
rubygems_version: 3.6.7
|
122
115
|
specification_version: 4
|
123
116
|
summary: An asynchronous adapter for ActionCable.
|
124
117
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# Released under the MIT License.
|
3
|
-
# Copyright, 2024, by Samuel Williams.
|
4
|
-
|
5
|
-
require "action_cable/subscription_adapter/base"
|
6
|
-
require "action_cable/subscription_adapter/channel_prefix"
|
7
|
-
require "action_cable/subscription_adapter/subscriber_map"
|
8
|
-
|
9
|
-
require "async/redis"
|
10
|
-
|
11
|
-
module ActionCable::SubscriptionAdapter
|
12
|
-
class AsyncCableRedis < Base
|
13
|
-
prepend ChannelPrefix
|
14
|
-
|
15
|
-
def initialize(*arguments, endpoint: nil, **options)
|
16
|
-
super(*arguments, **options)
|
17
|
-
|
18
|
-
@endpoint = endpoint || ::Async::Redis.local_endpoint
|
19
|
-
@client = ::Async::Redis::Client.new(endpoint)
|
20
|
-
|
21
|
-
@subscriber = Subscriber.new(@client, self.executor)
|
22
|
-
end
|
23
|
-
|
24
|
-
def subscribe(channel, callback, success_callback = nil)
|
25
|
-
@subscriber.add_subscriber(channel, callback, success_callback)
|
26
|
-
end
|
27
|
-
|
28
|
-
def unsubscribe(channel, callback)
|
29
|
-
@subscriber.remove_subscriber(channel, callback)
|
30
|
-
end
|
31
|
-
|
32
|
-
def broadcast(channel, payload)
|
33
|
-
@client.publish(channel, payload)
|
34
|
-
end
|
35
|
-
|
36
|
-
def shutdown
|
37
|
-
@subscriber&.close
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
class Subscriber < SubscriberMap::Async
|
43
|
-
CHANNEL = "_action_cable_internal"
|
44
|
-
|
45
|
-
def initialize(client, executor, parent: Async::Task.current)
|
46
|
-
super(executor)
|
47
|
-
|
48
|
-
@context = @client.subscribe(CHANNEL)
|
49
|
-
@task = parent.async{self.listen(CHANNEL)}
|
50
|
-
end
|
51
|
-
|
52
|
-
def add_channel(channel, on_success)
|
53
|
-
@context.subscribe(channel)
|
54
|
-
on_success&.call
|
55
|
-
end
|
56
|
-
|
57
|
-
def remove_channel(channel)
|
58
|
-
@context.unsubscribe(channel)
|
59
|
-
end
|
60
|
-
|
61
|
-
def close
|
62
|
-
if task = @task
|
63
|
-
@task = nil
|
64
|
-
task.stop
|
65
|
-
end
|
66
|
-
|
67
|
-
if context = @context
|
68
|
-
@context = nil
|
69
|
-
context.close
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def listen
|
76
|
-
context.each do |type, channel, message|
|
77
|
-
self.broadcast(event[1], event[2])
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|