anycable-core 1.5.1 โ 1.6.0.rc.1
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
- data/CHANGELOG.md +6 -1
- data/README.md +9 -57
- data/lib/anycable/grpc/rpc_services_pb.rb +1 -1
- data/lib/anycable/grpc_kit/health_pb.rb +4 -13
- data/lib/anycable/grpc_kit/server.rb +5 -0
- data/lib/anycable/jwt.rb +1 -0
- data/lib/anycable/protos/rpc_pb.rb +5 -55
- data/lib/anycable/rpc/handler.rb +13 -0
- data/lib/anycable/rpc/handlers/command.rb +2 -1
- data/lib/anycable/socket.rb +21 -3
- data/lib/anycable/version.rb +1 -1
- data/sig/anycable/health_server.rbs +2 -2
- data/sig/anycable/rpc/handler.rbs +1 -0
- data/sig/anycable/rpc.rbs +13 -1
- data/sig/anycable/socket.rbs +4 -0
- metadata +60 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a1e141540dbc11a56633dda1ba555de70900a37e3510f2c6404e50cc1375cfc
|
4
|
+
data.tar.gz: f51a96aa3b101fbd9a3dbfa66ec51109b3ff81897796a9e9a8d3fa2ba29ef0eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d021b6d6036e6d6d425ead93557688cb99d119f36276acae4474abb12b0aa58ada3bd380c48d8d154978449299dd23bb36e629a148be5b5a62831b51049c6ec
|
7
|
+
data.tar.gz: 7bd8f7d0abc547f8b61bab521d8ff96f4d58a5e5887982f597c7e71472bd8abb9179611bb28c29e236f5f4a89ac6c6f8f0a91f540b44f13785e4dcc8ccf8032f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.5.2 (2024-12-27)
|
6
|
+
|
7
|
+
- Update google-protobuf to version 4 (support Ruby 3.4). ([@le0pard][])
|
8
|
+
|
5
9
|
## 1.5.1 (2024-06-14) ๐ช๐บ โฝ๏ธ
|
6
10
|
|
7
11
|
- Fixed compatibility with Rack 3.1 ([@earlopain][])
|
@@ -209,10 +213,11 @@ See [#71](https://github.com/anycable/anycable/pull/71).
|
|
209
213
|
|
210
214
|
---
|
211
215
|
|
212
|
-
See [Changelog](https://github.com/anycable/anycable/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
|
216
|
+
See [Changelog](https://github.com/anycable/anycable-rb/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
|
213
217
|
|
214
218
|
[@palkan]: https://github.com/palkan
|
215
219
|
[@smasry]: https://github.com/smasry
|
216
220
|
[@Envek]: https://github.com/Envek
|
217
221
|
[@cylon-v]: https://github.com/cylon-v
|
218
222
|
[@earlopain]: https://github.com/earlopain
|
223
|
+
[@le0pard]: https://github.com/le0pard
|
data/README.md
CHANGED
@@ -1,77 +1,29 @@
|
|
1
1
|
[](https://rubygems.org/gems/anycable)
|
2
|
-
[](https://github.com/anycable/anycable/actions)
|
3
|
-
[](https://docs.anycable.io/v1)
|
2
|
+
[](https://github.com/anycable/anycable-rb/actions)
|
3
|
+
[](https://docs.anycable.io)
|
5
4
|
|
6
|
-
# AnyCable
|
5
|
+
# AnyCable Ruby SDK
|
7
6
|
|
8
7
|
<img align="right" height="150" width="129"
|
9
8
|
title="AnyCable logo" src="https://docs.anycable.io/assets/images/logo.svg">
|
10
9
|
|
11
|
-
AnyCable
|
10
|
+
[AnyCable](https://anycable.io) is an open-source language-agnostic realtime server for reliable two-way communication. This repository contains the Ruby SDK for AnyCable including RPC server implementations, broadcasting adapters and other utilities that could help you to integrate AnyCable into any Ruby application. For Rails integration, check out a dedicated gem: [anycable-rails](https://github.com/anycable/anycable-rails).
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
> [AnyCable Pro](https://docs.anycable.io/pro) has been launched ๐
|
16
|
-
|
17
|
-
<a href="https://evilmartians.com/">
|
18
|
-
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
12
|
+
๐ [Website](https://anycable.io) ยท ๐ [Documentation](https://docs.anycable.io/ruby/non_rails)
|
19
13
|
|
20
14
|
## Requirements
|
21
15
|
|
22
|
-
- Ruby
|
23
|
-
- Redis or NATS (for broadcasting **in production**, [discuss other options](https://github.com/anycable/anycable/issues/2) with us!)
|
24
|
-
|
25
|
-
## Usage
|
16
|
+
- Ruby 3.0+.
|
26
17
|
|
27
|
-
|
28
|
-
|
29
|
-
## Links
|
18
|
+
## Resources
|
30
19
|
|
31
20
|
- [AnyCable off Rails: connecting Twilio streams with Hanami](https://evilmartians.com/chronicles/anycable-goes-off-rails-connecting-twilio-streams-with-hanami)
|
32
21
|
|
33
|
-
- [AnyCable 1.0: Four years of real-time web with Ruby and Go](https://evilmartians.com/chronicles/anycable-1-0-four-years-of-real-time-web-with-ruby-and-go)
|
34
|
-
|
35
|
-
- [AnyCable: Action Cable on steroids!](https://evilmartians.com/chronicles/anycable-actioncable-on-steroids)
|
36
|
-
|
37
|
-
- [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)
|
38
|
-
|
39
|
-
- [From Action to Any](https://medium.com/@leshchuk/from-action-to-any-1e8d863dd4cf) by [@alekseyl](https://github.com/alekseyl)
|
40
|
-
|
41
|
-
## Talks
|
42
|
-
|
43
|
-
- High-speed cables for Ruby, RubyConf 2018, [slides](https://speakerdeck.com/palkan/rubyconf-2018-high-speed-cables-for-ruby) and [video](https://www.youtube.com/watch?v=8XRcOZXOzV4) (EN)
|
44
|
-
|
45
|
-
- One cable to rule them all, RubyKaigi 2018, [slides](https://speakerdeck.com/palkan/rubykaigi-2018-anycable-one-cable-to-rule-them-all) and [video](https://www.youtube.com/watch?v=jXCPuNICT8s) (EN)
|
46
|
-
|
47
|
-
- Wroc_Love.rb 2018 [slides](https://speakerdeck.com/palkan/wroc-love-dot-rb-2018-cables-cables-cables) and [video](https://www.youtube.com/watch?v=AUxFFOehiy0) (EN)
|
48
|
-
|
49
|
-
- RubyConfMY 2017 [slides](https://speakerdeck.com/palkan/rubyconf-malaysia-2017-anycable) and [video](https://www.youtube.com/watch?v=j5oFx525zNw) (EN)
|
50
|
-
|
51
|
-
- RailsClub Moscow 2016 [slides](https://speakerdeck.com/palkan/railsclub-moscow-2016-anycable) and [video](https://www.youtube.com/watch?v=-k7GQKuBevY&list=PLiWUIs1hSNeOXZhotgDX7Y7qBsr24cu7o&index=4) (RU)
|
52
|
-
|
53
|
-
## Building
|
54
|
-
|
55
|
-
### Generating gRPC files from `.proto`
|
56
|
-
|
57
|
-
- Install required GRPC gems:
|
58
|
-
|
59
|
-
```sh
|
60
|
-
gem install grpc
|
61
|
-
gem install grpc-tools
|
62
|
-
```
|
63
|
-
|
64
|
-
- Re-generate GRPC files (if necessary):
|
65
|
-
|
66
|
-
```sh
|
67
|
-
make
|
68
|
-
```
|
69
|
-
|
70
22
|
## Contributing
|
71
23
|
|
72
|
-
Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable](https://github.com/anycable/anycable).
|
24
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable-rb](https://github.com/anycable/anycable-rb).
|
73
25
|
|
74
|
-
Please, provide reproduction script (using [this template](https://github.com/anycable/anycable/blob/master/etc/bug_report_template.rb)) when submitting bugs if possible.
|
26
|
+
Please, provide reproduction script (using [this template](https://github.com/anycable/anycable-rb/blob/master/etc/bug_report_template.rb)) when submitting bugs if possible.
|
75
27
|
|
76
28
|
## License
|
77
29
|
|
@@ -5,19 +5,10 @@
|
|
5
5
|
|
6
6
|
require 'google/protobuf'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
add_message "grpc.health.v1.HealthCheckResponse" do
|
13
|
-
optional :status, :enum, 1, "grpc.health.v1.HealthCheckResponse.ServingStatus"
|
14
|
-
end
|
15
|
-
add_enum "grpc.health.v1.HealthCheckResponse.ServingStatus" do
|
16
|
-
value :UNKNOWN, 0
|
17
|
-
value :SERVING, 1
|
18
|
-
value :NOT_SERVING, 2
|
19
|
-
end
|
20
|
-
end
|
8
|
+
descriptor_data = "\n\x1bgrpc/health/v1/health.proto\x12\x0egrpc.health.v1\"%\n\x12HealthCheckRequest\x12\x0f\n\x07service\x18\x01 \x01(\t\"\xa9\x01\n\x13HealthCheckResponse\x12\x41\n\x06status\x18\x01 \x01(\x0e\x32\x31.grpc.health.v1.HealthCheckResponse.ServingStatus\"O\n\rServingStatus\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07SERVING\x10\x01\x12\x0f\n\x0bNOT_SERVING\x10\x02\x12\x13\n\x0fSERVICE_UNKNOWN\x10\x03\x32\xae\x01\n\x06Health\x12P\n\x05\x43heck\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse\x12R\n\x05Watch\x12\".grpc.health.v1.HealthCheckRequest\x1a#.grpc.health.v1.HealthCheckResponse0\x01\x42\x61\n\x11io.grpc.health.v1B\x0bHealthProtoP\x01Z,google.golang.org/grpc/health/grpc_health_v1\xaa\x02\x0eGrpc.Health.V1b\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
21
12
|
|
22
13
|
module Grpc
|
23
14
|
module Health
|
@@ -46,6 +46,7 @@ module AnyCable
|
|
46
46
|
|
47
47
|
@tls_credentials = options.delete(:tls_credentials)
|
48
48
|
@grpc_server = build_server(**options)
|
49
|
+
@sock = nil
|
49
50
|
end
|
50
51
|
|
51
52
|
# Start gRPC server in background and
|
@@ -63,6 +64,8 @@ module AnyCable
|
|
63
64
|
|
64
65
|
@start_thread = Thread.new do
|
65
66
|
loop do
|
67
|
+
break unless @sock
|
68
|
+
|
66
69
|
conn = @sock.accept
|
67
70
|
server.run(conn)
|
68
71
|
rescue IOError
|
@@ -118,6 +121,8 @@ module AnyCable
|
|
118
121
|
grpc_server.graceful_shutdown
|
119
122
|
sock.close
|
120
123
|
|
124
|
+
@sock = nil
|
125
|
+
|
121
126
|
logger.info "RPC server stopped"
|
122
127
|
end
|
123
128
|
|
data/lib/anycable/jwt.rb
CHANGED
@@ -5,65 +5,15 @@
|
|
5
5
|
|
6
6
|
require "google/protobuf"
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
map :headers, :string, :string, 2
|
13
|
-
map :cstate, :string, :string, 3
|
14
|
-
map :istate, :string, :string, 4
|
15
|
-
end
|
16
|
-
add_message "anycable.EnvResponse" do
|
17
|
-
map :cstate, :string, :string, 1
|
18
|
-
map :istate, :string, :string, 2
|
19
|
-
end
|
20
|
-
add_message "anycable.ConnectionRequest" do
|
21
|
-
optional :env, :message, 3, "anycable.Env"
|
22
|
-
end
|
23
|
-
add_message "anycable.ConnectionResponse" do
|
24
|
-
optional :status, :enum, 1, "anycable.Status"
|
25
|
-
optional :identifiers, :string, 2
|
26
|
-
repeated :transmissions, :string, 3
|
27
|
-
optional :error_msg, :string, 4
|
28
|
-
optional :env, :message, 5, "anycable.EnvResponse"
|
29
|
-
end
|
30
|
-
add_message "anycable.CommandMessage" do
|
31
|
-
optional :command, :string, 1
|
32
|
-
optional :identifier, :string, 2
|
33
|
-
optional :connection_identifiers, :string, 3
|
34
|
-
optional :data, :string, 4
|
35
|
-
optional :env, :message, 5, "anycable.Env"
|
36
|
-
end
|
37
|
-
add_message "anycable.CommandResponse" do
|
38
|
-
optional :status, :enum, 1, "anycable.Status"
|
39
|
-
optional :disconnect, :bool, 2
|
40
|
-
optional :stop_streams, :bool, 3
|
41
|
-
repeated :streams, :string, 4
|
42
|
-
repeated :transmissions, :string, 5
|
43
|
-
optional :error_msg, :string, 6
|
44
|
-
optional :env, :message, 7, "anycable.EnvResponse"
|
45
|
-
repeated :stopped_streams, :string, 8
|
46
|
-
end
|
47
|
-
add_message "anycable.DisconnectRequest" do
|
48
|
-
optional :identifiers, :string, 1
|
49
|
-
repeated :subscriptions, :string, 2
|
50
|
-
optional :env, :message, 5, "anycable.Env"
|
51
|
-
end
|
52
|
-
add_message "anycable.DisconnectResponse" do
|
53
|
-
optional :status, :enum, 1, "anycable.Status"
|
54
|
-
optional :error_msg, :string, 2
|
55
|
-
end
|
56
|
-
add_enum "anycable.Status" do
|
57
|
-
value :ERROR, 0
|
58
|
-
value :SUCCESS, 1
|
59
|
-
value :FAILURE, 2
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
8
|
+
descriptor_data = "\n\trpc.proto\x12\x08\x61nycable\"\xa3\x02\n\x03\x45nv\x12\x0b\n\x03url\x18\x01 \x01(\t\x12+\n\x07headers\x18\x02 \x03(\x0b\x32\x1a.anycable.Env.HeadersEntry\x12)\n\x06\x63state\x18\x03 \x03(\x0b\x32\x19.anycable.Env.CstateEntry\x12)\n\x06istate\x18\x04 \x03(\x0b\x32\x19.anycable.Env.IstateEntry\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0b\x43stateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bIstateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xd1\x01\n\x0b\x45nvResponse\x12\x31\n\x06\x63state\x18\x01 \x03(\x0b\x32!.anycable.EnvResponse.CstateEntry\x12\x31\n\x06istate\x18\x02 \x03(\x0b\x32!.anycable.EnvResponse.IstateEntry\x1a-\n\x0b\x43stateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a-\n\x0bIstateEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"G\n\x10PresenceResponse\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\t\x12\x0c\n\x04info\x18\x03 \x01(\t\x12\x0b\n\x03ttl\x18\x04 \x01(\r\"/\n\x11\x43onnectionRequest\x12\x1a\n\x03\x65nv\x18\x03 \x01(\x0b\x32\r.anycable.Env\"\x99\x01\n\x12\x43onnectionResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.anycable.Status\x12\x13\n\x0bidentifiers\x18\x02 \x01(\t\x12\x15\n\rtransmissions\x18\x03 \x03(\t\x12\x11\n\terror_msg\x18\x04 \x01(\t\x12\"\n\x03\x65nv\x18\x05 \x01(\x0b\x32\x15.anycable.EnvResponse\"\x7f\n\x0e\x43ommandMessage\x12\x0f\n\x07\x63ommand\x18\x01 \x01(\t\x12\x12\n\nidentifier\x18\x02 \x01(\t\x12\x1e\n\x16\x63onnection_identifiers\x18\x03 \x01(\t\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\t\x12\x1a\n\x03\x65nv\x18\x05 \x01(\x0b\x32\r.anycable.Env\"\x83\x02\n\x0f\x43ommandResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.anycable.Status\x12\x12\n\ndisconnect\x18\x02 \x01(\x08\x12\x14\n\x0cstop_streams\x18\x03 \x01(\x08\x12\x0f\n\x07streams\x18\x04 \x03(\t\x12\x15\n\rtransmissions\x18\x05 \x03(\t\x12\x11\n\terror_msg\x18\x06 \x01(\t\x12\"\n\x03\x65nv\x18\x07 \x01(\x0b\x32\x15.anycable.EnvResponse\x12\x17\n\x0fstopped_streams\x18\x08 \x03(\t\x12,\n\x08presence\x18\t \x01(\x0b\x32\x1a.anycable.PresenceResponse\"[\n\x11\x44isconnectRequest\x12\x13\n\x0bidentifiers\x18\x01 \x01(\t\x12\x15\n\rsubscriptions\x18\x02 \x03(\t\x12\x1a\n\x03\x65nv\x18\x05 \x01(\x0b\x32\r.anycable.Env\"I\n\x12\x44isconnectResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.anycable.Status\x12\x11\n\terror_msg\x18\x02 \x01(\t*-\n\x06Status\x12\t\n\x05\x45RROR\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x0b\n\x07\x46\x41ILURE\x10\x02\x32\xda\x01\n\x03RPC\x12\x46\n\x07\x43onnect\x12\x1b.anycable.ConnectionRequest\x1a\x1c.anycable.ConnectionResponse\"\x00\x12@\n\x07\x43ommand\x12\x18.anycable.CommandMessage\x1a\x19.anycable.CommandResponse\"\x00\x12I\n\nDisconnect\x12\x1b.anycable.DisconnectRequest\x1a\x1c.anycable.DisconnectResponse\"\x00\x42\x0b\xea\x02\x08\x41nyCableb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
63
12
|
|
64
13
|
module AnyCable
|
65
14
|
Env = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.Env").msgclass
|
66
15
|
EnvResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.EnvResponse").msgclass
|
16
|
+
PresenceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.PresenceResponse").msgclass
|
67
17
|
ConnectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.ConnectionRequest").msgclass
|
68
18
|
ConnectionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.ConnectionResponse").msgclass
|
69
19
|
CommandMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("anycable.CommandMessage").msgclass
|
data/lib/anycable/rpc/handler.rb
CHANGED
@@ -42,6 +42,19 @@ module AnyCable
|
|
42
42
|
)
|
43
43
|
end
|
44
44
|
|
45
|
+
def build_presence_response(socket)
|
46
|
+
return unless socket.presence
|
47
|
+
|
48
|
+
info = socket.presence[:info]
|
49
|
+
info = info.to_json if info && !info.is_a?(String)
|
50
|
+
|
51
|
+
AnyCable::PresenceResponse.new(
|
52
|
+
type: socket.presence.fetch(:type),
|
53
|
+
id: socket.presence.fetch(:id),
|
54
|
+
info: info
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
45
58
|
def logger
|
46
59
|
AnyCable.logger
|
47
60
|
end
|
@@ -27,7 +27,8 @@ module AnyCable
|
|
27
27
|
streams: socket.streams[:start],
|
28
28
|
stopped_streams: socket.streams[:stop],
|
29
29
|
transmissions: socket.transmissions,
|
30
|
-
env: build_env_response(socket)
|
30
|
+
env: build_env_response(socket),
|
31
|
+
presence: build_presence_response(socket)
|
31
32
|
)
|
32
33
|
end
|
33
34
|
end
|
data/lib/anycable/socket.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "stringio"
|
4
|
+
|
3
5
|
module AnyCable
|
4
6
|
WHISPER_KEY = "$w"
|
7
|
+
PRESENCE_KEY = "$p"
|
5
8
|
|
6
9
|
# Socket mock to be used with application connection
|
7
10
|
class Socket
|
@@ -44,7 +47,7 @@ module AnyCable
|
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
|
-
attr_reader :transmissions
|
50
|
+
attr_reader :transmissions, :presence
|
48
51
|
|
49
52
|
def initialize(env:)
|
50
53
|
@transmissions = []
|
@@ -56,11 +59,11 @@ module AnyCable
|
|
56
59
|
end
|
57
60
|
|
58
61
|
def subscribe(_channel, broadcasting)
|
59
|
-
streams[:start] << broadcasting
|
62
|
+
streams[:start] << broadcasting unless streams[:start].include?(broadcasting)
|
60
63
|
end
|
61
64
|
|
62
65
|
def unsubscribe(_channel, broadcasting)
|
63
|
-
streams[:stop] << broadcasting
|
66
|
+
streams[:stop] << broadcasting unless streams[:stop].include?(broadcasting)
|
64
67
|
|
65
68
|
if istate.read(WHISPER_KEY) == broadcasting
|
66
69
|
istate.write(WHISPER_KEY, "")
|
@@ -71,6 +74,21 @@ module AnyCable
|
|
71
74
|
istate.write(WHISPER_KEY, broadcasting)
|
72
75
|
end
|
73
76
|
|
77
|
+
def presence_join(broadcasting, id, info)
|
78
|
+
raise ArgumentError, "ID is required for presence tracking" unless id
|
79
|
+
|
80
|
+
subscribe("", broadcasting)
|
81
|
+
istate.write(PRESENCE_KEY, broadcasting)
|
82
|
+
|
83
|
+
@presence = {type: "join", id: id, info: info}.compact
|
84
|
+
end
|
85
|
+
|
86
|
+
def presence_leave(id)
|
87
|
+
raise ArgumentError, "ID is required for presence tracking" unless id
|
88
|
+
|
89
|
+
@presence = {type: "leave", id: id}
|
90
|
+
end
|
91
|
+
|
74
92
|
def unsubscribe_from_all(_channel)
|
75
93
|
@stop_all_streams = true
|
76
94
|
if istate.read(WHISPER_KEY)
|
data/lib/anycable/version.rb
CHANGED
@@ -4,8 +4,8 @@ module AnyCable
|
|
4
4
|
def running?: () -> bool
|
5
5
|
end
|
6
6
|
|
7
|
-
SUCCESS_RESPONSE:
|
8
|
-
FAILURE_RESPONSE:
|
7
|
+
SUCCESS_RESPONSE: [Integer, String]
|
8
|
+
FAILURE_RESPONSE: [Integer, String]
|
9
9
|
|
10
10
|
attr_reader server: _Runnable
|
11
11
|
attr_reader port: Integer
|
@@ -3,6 +3,7 @@ module AnyCable
|
|
3
3
|
interface _Handler
|
4
4
|
def build_socket: (env: Env) -> Socket
|
5
5
|
def build_env_response: (Socket socket) -> EnvResponse
|
6
|
+
def build_presence_response: (Socket socket) -> PresenceResponse?
|
6
7
|
def logger: () -> Logger
|
7
8
|
def factory: () -> _ConnectionFactory
|
8
9
|
end
|
data/sig/anycable/rpc.rbs
CHANGED
@@ -41,6 +41,16 @@ module AnyCable
|
|
41
41
|
def initialize: (?cstate: protoMap?, ?istate: protoMap?) -> void
|
42
42
|
end
|
43
43
|
|
44
|
+
type presenceEvent = "join" | "leave" | "update"
|
45
|
+
|
46
|
+
class PresenceResponse
|
47
|
+
attr_accessor type: presenceEvent
|
48
|
+
attr_accessor id: String
|
49
|
+
attr_accessor info: String?
|
50
|
+
|
51
|
+
def initialize: (?type: presenceEvent, ?id: String, ?info: String) -> void
|
52
|
+
end
|
53
|
+
|
44
54
|
interface _ProtoMessage
|
45
55
|
def initialize: (**untyped) -> void
|
46
56
|
end
|
@@ -130,6 +140,7 @@ module AnyCable
|
|
130
140
|
attr_accessor error_msg: String?
|
131
141
|
attr_accessor env: EnvResponse
|
132
142
|
attr_accessor stopped_streams: Array[String]
|
143
|
+
attr_accessor presence: PresenceResponse
|
133
144
|
|
134
145
|
%a{rbs:test:skip} def initialize: (
|
135
146
|
status: rpcStatus,
|
@@ -139,7 +150,8 @@ module AnyCable
|
|
139
150
|
?stopped_streams: Array[String],
|
140
151
|
?transmissions: Array[String],
|
141
152
|
?error_msg: String,
|
142
|
-
?env: EnvResponse
|
153
|
+
?env: EnvResponse?,
|
154
|
+
?presence: PresenceResponse?
|
143
155
|
) -> void
|
144
156
|
|
145
157
|
def to_h: () -> Hash[Symbol, untyped]
|
data/sig/anycable/socket.rbs
CHANGED
@@ -15,6 +15,7 @@ module AnyCable
|
|
15
15
|
|
16
16
|
attr_reader transmissions: Array[String]
|
17
17
|
attr_reader request_env: Env
|
18
|
+
attr_reader presence: Hash[Symbol, untyped]?
|
18
19
|
|
19
20
|
def initialize: (env: Env) -> void
|
20
21
|
def transmit: (String) -> void
|
@@ -30,6 +31,9 @@ module AnyCable
|
|
30
31
|
def env: () -> Hash[String, untyped]
|
31
32
|
def cstate: () -> State
|
32
33
|
def istate: () -> State
|
34
|
+
def whisper: (String, String) -> void
|
35
|
+
def presence_join: (String, String, String | Hash[untyped, untyped]) -> void
|
36
|
+
def presence_leave: (String) -> void
|
33
37
|
|
34
38
|
private
|
35
39
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anycable-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0.rc.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Vladimir Dementyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: anyway_config
|
@@ -24,20 +24,48 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: base64
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.2'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: google-protobuf
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - "~>"
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
47
|
+
version: '4'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: stringio
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3'
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3
|
68
|
+
version: '3'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: redis
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +136,20 @@ dependencies:
|
|
108
136
|
- - "~>"
|
109
137
|
- !ruby/object:Gem::Version
|
110
138
|
version: '3.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
111
153
|
- !ruby/object:Gem::Dependency
|
112
154
|
name: rspec
|
113
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,16 +212,16 @@ dependencies:
|
|
170
212
|
requirements:
|
171
213
|
- - ">="
|
172
214
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
215
|
+
version: 1.9.1
|
174
216
|
type: :development
|
175
217
|
prerelease: false
|
176
218
|
version_requirements: !ruby/object:Gem::Requirement
|
177
219
|
requirements:
|
178
220
|
- - ">="
|
179
221
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
181
|
-
description:
|
182
|
-
|
222
|
+
version: 1.9.1
|
223
|
+
description: Ruby SDK for AnyCable, an open-source realtime server for reliable two-way
|
224
|
+
communication
|
183
225
|
email:
|
184
226
|
- dementiev.vm@gmail.com
|
185
227
|
executables:
|
@@ -267,15 +309,15 @@ files:
|
|
267
309
|
- sig/anycable/streams.rbs
|
268
310
|
- sig/anycable/version.rbs
|
269
311
|
- sig/manifest.yml
|
270
|
-
homepage: http://github.com/anycable/anycable
|
312
|
+
homepage: http://github.com/anycable/anycable-rb
|
271
313
|
licenses:
|
272
314
|
- MIT
|
273
315
|
metadata:
|
274
|
-
bug_tracker_uri: http://github.com/anycable/anycable/issues
|
275
|
-
changelog_uri: https://github.com/anycable/anycable/blob/master/CHANGELOG.md
|
316
|
+
bug_tracker_uri: http://github.com/anycable/anycable-rb/issues
|
317
|
+
changelog_uri: https://github.com/anycable/anycable-rb/blob/master/CHANGELOG.md
|
276
318
|
documentation_uri: https://docs.anycable.io/
|
277
319
|
homepage_uri: https://anycable.io/
|
278
|
-
source_code_uri: http://github.com/anycable/anycable
|
320
|
+
source_code_uri: http://github.com/anycable/anycable-rb
|
279
321
|
funding_uri: https://github.com/sponsors/anycable
|
280
322
|
post_install_message:
|
281
323
|
rdoc_options: []
|
@@ -285,15 +327,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
285
327
|
requirements:
|
286
328
|
- - ">="
|
287
329
|
- !ruby/object:Gem::Version
|
288
|
-
version: 2.7
|
330
|
+
version: '2.7'
|
289
331
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
290
332
|
requirements:
|
291
|
-
- - "
|
333
|
+
- - ">"
|
292
334
|
- !ruby/object:Gem::Version
|
293
|
-
version:
|
335
|
+
version: 1.3.1
|
294
336
|
requirements: []
|
295
337
|
rubygems_version: 3.4.19
|
296
338
|
signing_key:
|
297
339
|
specification_version: 4
|
298
|
-
summary: AnyCable
|
340
|
+
summary: Ruby SDK for AnyCable, an open-source realtime server for reliable two-way
|
341
|
+
communication
|
299
342
|
test_files: []
|