actioncable 7.0.8.7 → 7.2.2.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 +34 -180
- data/MIT-LICENSE +1 -1
- data/README.md +4 -4
- data/app/assets/javascripts/action_cable.js +30 -9
- data/app/assets/javascripts/actioncable.esm.js +30 -9
- data/app/assets/javascripts/actioncable.js +30 -9
- data/lib/action_cable/channel/base.rb +114 -90
- data/lib/action_cable/channel/broadcasting.rb +25 -16
- data/lib/action_cable/channel/callbacks.rb +39 -0
- data/lib/action_cable/channel/naming.rb +10 -7
- data/lib/action_cable/channel/periodic_timers.rb +7 -7
- data/lib/action_cable/channel/streams.rb +77 -62
- data/lib/action_cable/channel/test_case.rb +117 -86
- data/lib/action_cable/connection/authorization.rb +4 -1
- data/lib/action_cable/connection/base.rb +70 -42
- data/lib/action_cable/connection/callbacks.rb +57 -0
- data/lib/action_cable/connection/client_socket.rb +3 -1
- data/lib/action_cable/connection/identification.rb +9 -5
- data/lib/action_cable/connection/internal_channel.rb +7 -2
- data/lib/action_cable/connection/message_buffer.rb +4 -1
- data/lib/action_cable/connection/stream.rb +2 -2
- data/lib/action_cable/connection/stream_event_loop.rb +4 -4
- data/lib/action_cable/connection/subscriptions.rb +7 -2
- data/lib/action_cable/connection/tagged_logger_proxy.rb +12 -7
- data/lib/action_cable/connection/test_case.rb +67 -55
- data/lib/action_cable/connection/web_socket.rb +11 -7
- data/lib/action_cable/deprecator.rb +9 -0
- data/lib/action_cable/engine.rb +18 -8
- data/lib/action_cable/gem_version.rb +6 -4
- data/lib/action_cable/helpers/action_cable_helper.rb +21 -19
- data/lib/action_cable/remote_connections.rb +25 -13
- data/lib/action_cable/server/base.rb +29 -14
- data/lib/action_cable/server/broadcasting.rb +24 -16
- data/lib/action_cable/server/configuration.rb +27 -14
- data/lib/action_cable/server/connections.rb +13 -5
- data/lib/action_cable/server/worker/active_record_connection_management.rb +2 -0
- data/lib/action_cable/server/worker.rb +4 -3
- data/lib/action_cable/subscription_adapter/async.rb +1 -1
- data/lib/action_cable/subscription_adapter/base.rb +2 -0
- data/lib/action_cable/subscription_adapter/channel_prefix.rb +2 -0
- data/lib/action_cable/subscription_adapter/inline.rb +2 -0
- data/lib/action_cable/subscription_adapter/postgresql.rb +4 -3
- data/lib/action_cable/subscription_adapter/redis.rb +7 -7
- data/lib/action_cable/subscription_adapter/subscriber_map.rb +2 -0
- data/lib/action_cable/subscription_adapter/test.rb +6 -5
- data/lib/action_cable/test_case.rb +2 -0
- data/lib/action_cable/test_helper.rb +89 -59
- data/lib/action_cable/version.rb +3 -1
- data/lib/action_cable.rb +30 -12
- data/lib/rails/generators/channel/USAGE +14 -8
- data/lib/rails/generators/channel/channel_generator.rb +23 -7
- data/lib/rails/generators/test_unit/channel_generator.rb +2 -0
- metadata +27 -15
- data/lib/action_cable/channel.rb +0 -17
- data/lib/action_cable/connection.rb +0 -22
- data/lib/action_cable/server.rb +0 -16
- data/lib/action_cable/subscription_adapter.rb +0 -12
- /data/lib/rails/generators/channel/templates/application_cable/{channel.rb → channel.rb.tt} +0 -0
- /data/lib/rails/generators/channel/templates/application_cable/{connection.rb → connection.rb.tt} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 720238323d1411f0913bcc9b65ac89d955c4fc4e708bbab5b5dd1c0c47c4cf00
|
4
|
+
data.tar.gz: 10a5cd05102adeda05b151a39c40183bc55c2c55c2c63dca5a13d642fcf49f58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0639a73b1efc8078fe167814911d5694e76781f618ac7fe5bb34ae8448ab495b60f598a76c6a0e8d7c9f45d9674d19564ad14eaae0ccaaf1f75b441d1318d7c8'
|
7
|
+
data.tar.gz: 4988a92b2c683bc86c28d60be1d2f92d1efe36bc5d33f814da55ac7328af60597fb0313321aa663b6d5632ecd565661725d12bf1238fa48a153b18d538e6e08e
|
data/CHANGELOG.md
CHANGED
@@ -1,214 +1,68 @@
|
|
1
|
-
## Rails 7.
|
1
|
+
## Rails 7.2.2.1 (December 10, 2024) ##
|
2
2
|
|
3
3
|
* No changes.
|
4
4
|
|
5
5
|
|
6
|
-
## Rails 7.
|
6
|
+
## Rails 7.2.2 (October 30, 2024) ##
|
7
7
|
|
8
8
|
* No changes.
|
9
9
|
|
10
10
|
|
11
|
-
## Rails 7.
|
11
|
+
## Rails 7.2.1.2 (October 23, 2024) ##
|
12
12
|
|
13
13
|
* No changes.
|
14
14
|
|
15
15
|
|
16
|
-
## Rails 7.
|
16
|
+
## Rails 7.2.1.1 (October 15, 2024) ##
|
17
17
|
|
18
18
|
* No changes.
|
19
19
|
|
20
20
|
|
21
|
-
## Rails 7.
|
21
|
+
## Rails 7.2.1 (August 22, 2024) ##
|
22
22
|
|
23
23
|
* No changes.
|
24
24
|
|
25
25
|
|
26
|
-
## Rails 7.0
|
26
|
+
## Rails 7.2.0 (August 09, 2024) ##
|
27
27
|
|
28
|
-
*
|
29
|
-
|
30
|
-
|
31
|
-
## Rails 7.0.8.1 (February 21, 2024) ##
|
32
|
-
|
33
|
-
* No changes.
|
34
|
-
|
35
|
-
|
36
|
-
## Rails 7.0.8 (September 09, 2023) ##
|
37
|
-
|
38
|
-
* No changes.
|
39
|
-
|
40
|
-
|
41
|
-
## Rails 7.0.7.2 (August 22, 2023) ##
|
42
|
-
|
43
|
-
* No changes.
|
44
|
-
|
45
|
-
|
46
|
-
## Rails 7.0.7.1 (August 22, 2023) ##
|
47
|
-
|
48
|
-
* No changes.
|
49
|
-
|
50
|
-
|
51
|
-
## Rails 7.0.7 (August 09, 2023) ##
|
52
|
-
|
53
|
-
* No changes.
|
54
|
-
|
55
|
-
|
56
|
-
## Rails 7.0.6 (June 29, 2023) ##
|
57
|
-
|
58
|
-
* Fix Action Cable Redis configuration with sentinels.
|
59
|
-
|
60
|
-
*Dmitriy Ivliev*
|
61
|
-
|
62
|
-
|
63
|
-
## Rails 7.0.5.1 (June 26, 2023) ##
|
64
|
-
|
65
|
-
* No changes.
|
66
|
-
|
67
|
-
|
68
|
-
## Rails 7.0.5 (May 24, 2023) ##
|
69
|
-
|
70
|
-
* Restore Action Cable Redis pub/sub listener on connection failure.
|
71
|
-
|
72
|
-
*Vladimir Dementyev*
|
73
|
-
|
74
|
-
|
75
|
-
## Rails 7.0.4.3 (March 13, 2023) ##
|
76
|
-
|
77
|
-
* No changes.
|
78
|
-
|
79
|
-
|
80
|
-
## Rails 7.0.4.2 (January 24, 2023) ##
|
81
|
-
|
82
|
-
* No changes.
|
83
|
-
|
84
|
-
|
85
|
-
## Rails 7.0.4.1 (January 17, 2023) ##
|
86
|
-
|
87
|
-
* No changes.
|
88
|
-
|
89
|
-
|
90
|
-
## Rails 7.0.4 (September 09, 2022) ##
|
91
|
-
|
92
|
-
* The Redis adapter is now compatible with redis-rb 5.0
|
93
|
-
|
94
|
-
Compatibility with redis-rb 3.x was dropped.
|
95
|
-
|
96
|
-
*Jean Boussier*
|
97
|
-
|
98
|
-
* The Action Cable server is now mounted with `anchor: true`.
|
99
|
-
|
100
|
-
This means that routes that also start with `/cable` will no longer clash with Action Cable.
|
101
|
-
|
102
|
-
*Alex Ghiculescu*
|
103
|
-
|
104
|
-
|
105
|
-
## Rails 7.0.3.1 (July 12, 2022) ##
|
106
|
-
|
107
|
-
* No changes.
|
108
|
-
|
109
|
-
|
110
|
-
## Rails 7.0.3 (May 09, 2022) ##
|
111
|
-
|
112
|
-
* No changes.
|
113
|
-
|
114
|
-
|
115
|
-
## Rails 7.0.2.4 (April 26, 2022) ##
|
116
|
-
|
117
|
-
* No changes.
|
118
|
-
|
119
|
-
|
120
|
-
## Rails 7.0.2.3 (March 08, 2022) ##
|
121
|
-
|
122
|
-
* No changes.
|
123
|
-
|
124
|
-
|
125
|
-
## Rails 7.0.2.2 (February 11, 2022) ##
|
126
|
-
|
127
|
-
* No changes.
|
128
|
-
|
129
|
-
|
130
|
-
## Rails 7.0.2.1 (February 11, 2022) ##
|
131
|
-
|
132
|
-
* No changes.
|
133
|
-
|
134
|
-
|
135
|
-
## Rails 7.0.2 (February 08, 2022) ##
|
136
|
-
|
137
|
-
* No changes.
|
138
|
-
|
139
|
-
|
140
|
-
## Rails 7.0.1 (January 06, 2022) ##
|
141
|
-
|
142
|
-
* No changes.
|
143
|
-
|
144
|
-
|
145
|
-
## Rails 7.0.0 (December 15, 2021) ##
|
146
|
-
|
147
|
-
* No changes.
|
148
|
-
|
149
|
-
|
150
|
-
## Rails 7.0.0.rc3 (December 14, 2021) ##
|
151
|
-
|
152
|
-
* No changes.
|
153
|
-
|
154
|
-
|
155
|
-
## Rails 7.0.0.rc2 (December 14, 2021) ##
|
156
|
-
|
157
|
-
* No changes.
|
158
|
-
|
159
|
-
## Rails 7.0.0.rc1 (December 06, 2021) ##
|
160
|
-
|
161
|
-
* The Action Cable client now ensures successful channel subscriptions:
|
162
|
-
|
163
|
-
* The client maintains a set of pending subscriptions until either
|
164
|
-
the server confirms the subscription or the channel is torn down.
|
165
|
-
* Rectifies the race condition where an unsubscribe is rapidly followed
|
166
|
-
by a subscribe (on the same channel identifier) and the requests are
|
167
|
-
handled out of order by the ActionCable server, thereby ignoring the
|
168
|
-
subscribe command.
|
169
|
-
|
170
|
-
*Daniel Spinosa*
|
171
|
-
|
172
|
-
|
173
|
-
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
174
|
-
|
175
|
-
* No changes.
|
176
|
-
|
177
|
-
|
178
|
-
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
179
|
-
|
180
|
-
* Compile ESM package that can be used directly in the browser as actioncable.esm.js.
|
181
|
-
|
182
|
-
*DHH*
|
28
|
+
* Bring `ActionCable::Connection::TestCookieJar` in alignment with `ActionDispatch::Cookies::CookieJar` in regards to setting the cookie value.
|
183
29
|
|
184
|
-
|
30
|
+
Before:
|
185
31
|
|
186
|
-
|
32
|
+
```ruby
|
33
|
+
cookies[:foo] = { value: "bar" }
|
34
|
+
puts cookies[:foo] # => { value: "bar" }
|
35
|
+
```
|
187
36
|
|
188
|
-
|
37
|
+
After:
|
189
38
|
|
190
|
-
|
39
|
+
```ruby
|
40
|
+
cookies[:foo] = { value: "bar" }
|
41
|
+
puts cookies[:foo] # => "bar"
|
42
|
+
```
|
191
43
|
|
192
|
-
*
|
44
|
+
*Justin Ko*
|
193
45
|
|
194
|
-
|
46
|
+
* Record ping on every Action Cable message.
|
195
47
|
|
196
|
-
|
48
|
+
Previously only `ping` and `welcome` message types were keeping the connection active.
|
49
|
+
Now every Action Cable message updates the `pingedAt` value, preventing the connection
|
50
|
+
from being marked as stale.
|
197
51
|
|
198
|
-
*
|
52
|
+
*yauhenininjia*
|
199
53
|
|
200
|
-
*
|
201
|
-
|
54
|
+
* Add two new assertion methods for Action Cable test cases: `assert_has_no_stream`
|
55
|
+
and `assert_has_no_stream_for`.
|
202
56
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
* Subsequent reconnection attempts now use exponential backoff instead of
|
207
|
-
logarithmic backoff. To allow the delay between reconnection attempts to
|
208
|
-
increase slowly at first, the default exponentiation base is < 2.
|
209
|
-
* Random jitter is applied to each delay between reconnection attempts.
|
57
|
+
These methods can be used to assert that a stream has been stopped, e.g. via
|
58
|
+
`stop_stream` or `stop_stream_for`. They complement the already existing
|
59
|
+
`assert_has_stream` and `assert_has_stream_for` methods.
|
210
60
|
|
211
|
-
|
61
|
+
```ruby
|
62
|
+
assert_has_no_stream "messages"
|
63
|
+
assert_has_no_stream_for User.find(42)
|
64
|
+
```
|
212
65
|
|
66
|
+
*Sebastian Pöll*, *Junichi Sato*
|
213
67
|
|
214
|
-
Please check [
|
68
|
+
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/actioncable/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
# Action Cable – Integrated WebSockets for Rails
|
1
|
+
# Action Cable – Integrated WebSockets for \Rails
|
2
2
|
|
3
|
-
Action Cable seamlessly integrates WebSockets with the rest of your Rails application.
|
3
|
+
Action Cable seamlessly integrates WebSockets with the rest of your \Rails application.
|
4
4
|
It allows for real-time features to be written in Ruby in the same style
|
5
|
-
and form as the rest of your Rails application, while still being performant
|
5
|
+
and form as the rest of your \Rails application, while still being performant
|
6
6
|
and scalable. It's a full-stack offering that provides both a client-side
|
7
7
|
JavaScript framework and a server-side Ruby framework. You have access to your full
|
8
8
|
domain model written with Active Record or your ORM of choice.
|
9
9
|
|
10
|
-
You can read more about Action Cable in the [Action Cable Overview](https://
|
10
|
+
You can read more about Action Cable in the [Action Cable Overview](https://guides.rubyonrails.org/action_cable_overview.html) guide.
|
11
11
|
|
12
12
|
## Support
|
13
13
|
|
@@ -4,8 +4,8 @@
|
|
4
4
|
})(this, (function(exports) {
|
5
5
|
"use strict";
|
6
6
|
var adapters = {
|
7
|
-
logger:
|
8
|
-
WebSocket:
|
7
|
+
logger: typeof console !== "undefined" ? console : undefined,
|
8
|
+
WebSocket: typeof WebSocket !== "undefined" ? WebSocket : undefined
|
9
9
|
};
|
10
10
|
var logger = {
|
11
11
|
log(...messages) {
|
@@ -43,12 +43,11 @@
|
|
43
43
|
isRunning() {
|
44
44
|
return this.startedAt && !this.stoppedAt;
|
45
45
|
}
|
46
|
-
|
46
|
+
recordMessage() {
|
47
47
|
this.pingedAt = now();
|
48
48
|
}
|
49
49
|
recordConnect() {
|
50
50
|
this.reconnectAttempts = 0;
|
51
|
-
this.recordPing();
|
52
51
|
delete this.disconnectedAt;
|
53
52
|
logger.log("ConnectionMonitor recorded connect");
|
54
53
|
}
|
@@ -121,7 +120,8 @@
|
|
121
120
|
disconnect_reasons: {
|
122
121
|
unauthorized: "unauthorized",
|
123
122
|
invalid_request: "invalid_request",
|
124
|
-
server_restart: "server_restart"
|
123
|
+
server_restart: "server_restart",
|
124
|
+
remote: "remote"
|
125
125
|
},
|
126
126
|
default_mount_path: "/cable",
|
127
127
|
protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
|
@@ -150,11 +150,12 @@
|
|
150
150
|
logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
|
151
151
|
return false;
|
152
152
|
} else {
|
153
|
-
|
153
|
+
const socketProtocols = [ ...protocols, ...this.consumer.subprotocols || [] ];
|
154
|
+
logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`);
|
154
155
|
if (this.webSocket) {
|
155
156
|
this.uninstallEventHandlers();
|
156
157
|
}
|
157
|
-
this.webSocket = new adapters.WebSocket(this.consumer.url,
|
158
|
+
this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols);
|
158
159
|
this.installEventHandlers();
|
159
160
|
this.monitor.start();
|
160
161
|
return true;
|
@@ -196,6 +197,9 @@
|
|
196
197
|
isActive() {
|
197
198
|
return this.isState("open", "connecting");
|
198
199
|
}
|
200
|
+
triedToReconnect() {
|
201
|
+
return this.monitor.reconnectAttempts > 0;
|
202
|
+
}
|
199
203
|
isProtocolSupported() {
|
200
204
|
return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
|
201
205
|
}
|
@@ -231,8 +235,12 @@
|
|
231
235
|
return;
|
232
236
|
}
|
233
237
|
const {identifier: identifier, message: message, reason: reason, reconnect: reconnect, type: type} = JSON.parse(event.data);
|
238
|
+
this.monitor.recordMessage();
|
234
239
|
switch (type) {
|
235
240
|
case message_types.welcome:
|
241
|
+
if (this.triedToReconnect()) {
|
242
|
+
this.reconnectAttempted = true;
|
243
|
+
}
|
236
244
|
this.monitor.recordConnect();
|
237
245
|
return this.subscriptions.reload();
|
238
246
|
|
@@ -243,11 +251,20 @@
|
|
243
251
|
});
|
244
252
|
|
245
253
|
case message_types.ping:
|
246
|
-
return
|
254
|
+
return null;
|
247
255
|
|
248
256
|
case message_types.confirmation:
|
249
257
|
this.subscriptions.confirmSubscription(identifier);
|
250
|
-
|
258
|
+
if (this.reconnectAttempted) {
|
259
|
+
this.reconnectAttempted = false;
|
260
|
+
return this.subscriptions.notify(identifier, "connected", {
|
261
|
+
reconnected: true
|
262
|
+
});
|
263
|
+
} else {
|
264
|
+
return this.subscriptions.notify(identifier, "connected", {
|
265
|
+
reconnected: false
|
266
|
+
});
|
267
|
+
}
|
251
268
|
|
252
269
|
case message_types.rejection:
|
253
270
|
return this.subscriptions.reject(identifier);
|
@@ -427,6 +444,7 @@
|
|
427
444
|
this._url = url;
|
428
445
|
this.subscriptions = new Subscriptions(this);
|
429
446
|
this.connection = new Connection(this);
|
447
|
+
this.subprotocols = [];
|
430
448
|
}
|
431
449
|
get url() {
|
432
450
|
return createWebSocketURL(this._url);
|
@@ -447,6 +465,9 @@
|
|
447
465
|
return this.connection.open();
|
448
466
|
}
|
449
467
|
}
|
468
|
+
addSubProtocol(subprotocol) {
|
469
|
+
this.subprotocols = [ ...this.subprotocols, subprotocol ];
|
470
|
+
}
|
450
471
|
}
|
451
472
|
function createWebSocketURL(url) {
|
452
473
|
if (typeof url === "function") {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
var adapters = {
|
2
|
-
logger:
|
3
|
-
WebSocket:
|
2
|
+
logger: typeof console !== "undefined" ? console : undefined,
|
3
|
+
WebSocket: typeof WebSocket !== "undefined" ? WebSocket : undefined
|
4
4
|
};
|
5
5
|
|
6
6
|
var logger = {
|
@@ -42,12 +42,11 @@ class ConnectionMonitor {
|
|
42
42
|
isRunning() {
|
43
43
|
return this.startedAt && !this.stoppedAt;
|
44
44
|
}
|
45
|
-
|
45
|
+
recordMessage() {
|
46
46
|
this.pingedAt = now();
|
47
47
|
}
|
48
48
|
recordConnect() {
|
49
49
|
this.reconnectAttempts = 0;
|
50
|
-
this.recordPing();
|
51
50
|
delete this.disconnectedAt;
|
52
51
|
logger.log("ConnectionMonitor recorded connect");
|
53
52
|
}
|
@@ -123,7 +122,8 @@ var INTERNAL = {
|
|
123
122
|
disconnect_reasons: {
|
124
123
|
unauthorized: "unauthorized",
|
125
124
|
invalid_request: "invalid_request",
|
126
|
-
server_restart: "server_restart"
|
125
|
+
server_restart: "server_restart",
|
126
|
+
remote: "remote"
|
127
127
|
},
|
128
128
|
default_mount_path: "/cable",
|
129
129
|
protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
|
@@ -156,11 +156,12 @@ class Connection {
|
|
156
156
|
logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
|
157
157
|
return false;
|
158
158
|
} else {
|
159
|
-
|
159
|
+
const socketProtocols = [ ...protocols, ...this.consumer.subprotocols || [] ];
|
160
|
+
logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`);
|
160
161
|
if (this.webSocket) {
|
161
162
|
this.uninstallEventHandlers();
|
162
163
|
}
|
163
|
-
this.webSocket = new adapters.WebSocket(this.consumer.url,
|
164
|
+
this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols);
|
164
165
|
this.installEventHandlers();
|
165
166
|
this.monitor.start();
|
166
167
|
return true;
|
@@ -202,6 +203,9 @@ class Connection {
|
|
202
203
|
isActive() {
|
203
204
|
return this.isState("open", "connecting");
|
204
205
|
}
|
206
|
+
triedToReconnect() {
|
207
|
+
return this.monitor.reconnectAttempts > 0;
|
208
|
+
}
|
205
209
|
isProtocolSupported() {
|
206
210
|
return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
|
207
211
|
}
|
@@ -239,8 +243,12 @@ Connection.prototype.events = {
|
|
239
243
|
return;
|
240
244
|
}
|
241
245
|
const {identifier: identifier, message: message, reason: reason, reconnect: reconnect, type: type} = JSON.parse(event.data);
|
246
|
+
this.monitor.recordMessage();
|
242
247
|
switch (type) {
|
243
248
|
case message_types.welcome:
|
249
|
+
if (this.triedToReconnect()) {
|
250
|
+
this.reconnectAttempted = true;
|
251
|
+
}
|
244
252
|
this.monitor.recordConnect();
|
245
253
|
return this.subscriptions.reload();
|
246
254
|
|
@@ -251,11 +259,20 @@ Connection.prototype.events = {
|
|
251
259
|
});
|
252
260
|
|
253
261
|
case message_types.ping:
|
254
|
-
return
|
262
|
+
return null;
|
255
263
|
|
256
264
|
case message_types.confirmation:
|
257
265
|
this.subscriptions.confirmSubscription(identifier);
|
258
|
-
|
266
|
+
if (this.reconnectAttempted) {
|
267
|
+
this.reconnectAttempted = false;
|
268
|
+
return this.subscriptions.notify(identifier, "connected", {
|
269
|
+
reconnected: true
|
270
|
+
});
|
271
|
+
} else {
|
272
|
+
return this.subscriptions.notify(identifier, "connected", {
|
273
|
+
reconnected: false
|
274
|
+
});
|
275
|
+
}
|
259
276
|
|
260
277
|
case message_types.rejection:
|
261
278
|
return this.subscriptions.reject(identifier);
|
@@ -440,6 +457,7 @@ class Consumer {
|
|
440
457
|
this._url = url;
|
441
458
|
this.subscriptions = new Subscriptions(this);
|
442
459
|
this.connection = new Connection(this);
|
460
|
+
this.subprotocols = [];
|
443
461
|
}
|
444
462
|
get url() {
|
445
463
|
return createWebSocketURL(this._url);
|
@@ -460,6 +478,9 @@ class Consumer {
|
|
460
478
|
return this.connection.open();
|
461
479
|
}
|
462
480
|
}
|
481
|
+
addSubProtocol(subprotocol) {
|
482
|
+
this.subprotocols = [ ...this.subprotocols, subprotocol ];
|
483
|
+
}
|
463
484
|
}
|
464
485
|
|
465
486
|
function createWebSocketURL(url) {
|
@@ -4,8 +4,8 @@
|
|
4
4
|
})(this, (function(exports) {
|
5
5
|
"use strict";
|
6
6
|
var adapters = {
|
7
|
-
logger:
|
8
|
-
WebSocket:
|
7
|
+
logger: typeof console !== "undefined" ? console : undefined,
|
8
|
+
WebSocket: typeof WebSocket !== "undefined" ? WebSocket : undefined
|
9
9
|
};
|
10
10
|
var logger = {
|
11
11
|
log(...messages) {
|
@@ -43,12 +43,11 @@
|
|
43
43
|
isRunning() {
|
44
44
|
return this.startedAt && !this.stoppedAt;
|
45
45
|
}
|
46
|
-
|
46
|
+
recordMessage() {
|
47
47
|
this.pingedAt = now();
|
48
48
|
}
|
49
49
|
recordConnect() {
|
50
50
|
this.reconnectAttempts = 0;
|
51
|
-
this.recordPing();
|
52
51
|
delete this.disconnectedAt;
|
53
52
|
logger.log("ConnectionMonitor recorded connect");
|
54
53
|
}
|
@@ -121,7 +120,8 @@
|
|
121
120
|
disconnect_reasons: {
|
122
121
|
unauthorized: "unauthorized",
|
123
122
|
invalid_request: "invalid_request",
|
124
|
-
server_restart: "server_restart"
|
123
|
+
server_restart: "server_restart",
|
124
|
+
remote: "remote"
|
125
125
|
},
|
126
126
|
default_mount_path: "/cable",
|
127
127
|
protocols: [ "actioncable-v1-json", "actioncable-unsupported" ]
|
@@ -150,11 +150,12 @@
|
|
150
150
|
logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
|
151
151
|
return false;
|
152
152
|
} else {
|
153
|
-
|
153
|
+
const socketProtocols = [ ...protocols, ...this.consumer.subprotocols || [] ];
|
154
|
+
logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`);
|
154
155
|
if (this.webSocket) {
|
155
156
|
this.uninstallEventHandlers();
|
156
157
|
}
|
157
|
-
this.webSocket = new adapters.WebSocket(this.consumer.url,
|
158
|
+
this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols);
|
158
159
|
this.installEventHandlers();
|
159
160
|
this.monitor.start();
|
160
161
|
return true;
|
@@ -196,6 +197,9 @@
|
|
196
197
|
isActive() {
|
197
198
|
return this.isState("open", "connecting");
|
198
199
|
}
|
200
|
+
triedToReconnect() {
|
201
|
+
return this.monitor.reconnectAttempts > 0;
|
202
|
+
}
|
199
203
|
isProtocolSupported() {
|
200
204
|
return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
|
201
205
|
}
|
@@ -231,8 +235,12 @@
|
|
231
235
|
return;
|
232
236
|
}
|
233
237
|
const {identifier: identifier, message: message, reason: reason, reconnect: reconnect, type: type} = JSON.parse(event.data);
|
238
|
+
this.monitor.recordMessage();
|
234
239
|
switch (type) {
|
235
240
|
case message_types.welcome:
|
241
|
+
if (this.triedToReconnect()) {
|
242
|
+
this.reconnectAttempted = true;
|
243
|
+
}
|
236
244
|
this.monitor.recordConnect();
|
237
245
|
return this.subscriptions.reload();
|
238
246
|
|
@@ -243,11 +251,20 @@
|
|
243
251
|
});
|
244
252
|
|
245
253
|
case message_types.ping:
|
246
|
-
return
|
254
|
+
return null;
|
247
255
|
|
248
256
|
case message_types.confirmation:
|
249
257
|
this.subscriptions.confirmSubscription(identifier);
|
250
|
-
|
258
|
+
if (this.reconnectAttempted) {
|
259
|
+
this.reconnectAttempted = false;
|
260
|
+
return this.subscriptions.notify(identifier, "connected", {
|
261
|
+
reconnected: true
|
262
|
+
});
|
263
|
+
} else {
|
264
|
+
return this.subscriptions.notify(identifier, "connected", {
|
265
|
+
reconnected: false
|
266
|
+
});
|
267
|
+
}
|
251
268
|
|
252
269
|
case message_types.rejection:
|
253
270
|
return this.subscriptions.reject(identifier);
|
@@ -427,6 +444,7 @@
|
|
427
444
|
this._url = url;
|
428
445
|
this.subscriptions = new Subscriptions(this);
|
429
446
|
this.connection = new Connection(this);
|
447
|
+
this.subprotocols = [];
|
430
448
|
}
|
431
449
|
get url() {
|
432
450
|
return createWebSocketURL(this._url);
|
@@ -447,6 +465,9 @@
|
|
447
465
|
return this.connection.open();
|
448
466
|
}
|
449
467
|
}
|
468
|
+
addSubProtocol(subprotocol) {
|
469
|
+
this.subprotocols = [ ...this.subprotocols, subprotocol ];
|
470
|
+
}
|
450
471
|
}
|
451
472
|
function createWebSocketURL(url) {
|
452
473
|
if (typeof url === "function") {
|