Commit Graph

68 Commits

Author SHA1 Message Date
Takuya Noguchi
b6e49a7b1f chore(deps-dev): update eslint from 4.3.0 to 8.40.0
Also update eslint-plugin-import from 2.27.5 to 2.29.0.

Signed-off-by: Takuya Noguchi <takninnovationresearch@gmail.com>
2024-05-23 14:23:15 +09:00
yauhenisushkevich
2a71de9cca
Record ping on every actioncable message 2024-04-05 15:23:52 +00:00
Zane Wolfgang Pickett
f634121c3d
Fix self is undefined for actioncable within ssr build systems by replacing it globalThis 2024-01-03 19:19:50 +00:00
Jonathan Hefner
4dcd6ba8d3 Update .gitattributes for generated JavaScript [ci-skip]
This adds `linguist-generated` and `linguist-vendored` attributes where
appropriate to suppress the files in diffs and exclude the files from
the project's language stats on GitHub.

See https://github.com/github/linguist for more information.
2023-11-05 15:48:08 -06:00
Guillaume Hain
6edb465bcf
Allows adding more protocols to the WebSocket sub protocols 2022-10-19 09:00:15 +02:00
mansakondo
3a6ab41595 Fix #45738 2022-09-25 14:57:32 +02:00
mansakondo
27a967ef70 Add ability to handle reconnects with the connected() callback 2022-09-14 12:14:58 +02:00
Vladimir Dementyev
2d0f9c5844 Send disconnect message during remote disconnect
Send {type: :disconnect} message to a client before closing the connection when initiated by server.remote_connections.where(...).disconnect
2022-05-11 13:59:23 -04:00
Jorge Manrubia
ed8e767218
Only close websockets when connection is open (#44304)
This addresses a problem where Safari's websockets gets permanently broken
when closing them in a "connecting" state.

See https://github.com/rails/rails/issues/43835#issuecomment-1002288478
2022-02-02 15:50:34 +01:00
Dan Spinosa
6d7c12274e
Client ensures subscribe command is confirmed. (#41581)
A SubscriptionGuarantor maintains a set of pending subscriptions,
resending the subscribe command unless and until the subscription
is confirmed or rejected by the server or cancelled client-side.

A race condition in the ActionCable server - where an unsubscribe
is sent, followed rapidly by a subscribe, but handled in the reverse
order - necessitates this enhancement.  Indeed, the subscriptions created
and torn down by Turbo Streams amplifies the existence of this race
condition.
2021-09-26 10:06:27 -07:00
David Heinemeier Hansson
4a23cb3415
Output Action Cable JS without transpiling and as ESM (#42856)
* Output Action Cable JS without transpiling and as ESM

* Retain umd version under the old name, generate ESM version + duplicate under new name

* Precompile JavaScripts for direct asset pipeline use

* We've dropped support for IE11

* Include deprecation notice for the old file reference

Thanks @rafaelfranca 👍

* Allow app to opt out of precompiling actioncable js assets

cc @rafaelfranca

* Add changelog entries
2021-08-06 14:00:43 +02:00
Jonathan Hefner
cc9a9e8503 Prevent thundering herd of Action Cable clients
This commit makes a few changes to the Action Cable client to prevent a
"thundering herd" of client reconnects after server connectivity loss:

* The client will wait a random amount between 1x and 3x of the stale
  threshold after the server's last ping before making the first
  reconnection attempt.
* Subsequent reconnection attempts now use exponential backoff instead
  of logarithmic backoff.  To allow the delay between reconnection
  attempts to increase slowly at first, the default exponentiation base
  is < 2.
* Random jitter is applied to each delay between reconnection attempts.

Co-authored-by: John Williams <john@veloshots.com>
2021-02-02 10:43:05 -06:00
Jonathan Hefner
fd3fd618f4 Add gitattributes for vendored and generated files [ci-skip]
The `linguist-vendored` attribute excludes the specified file from the
project's language stats on GitHub.  The `linguist-generated` attribute
does the same, and also suppresses that file in diffs on GitHub.

See https://github.com/github/linguist for more information.
2020-10-04 16:44:37 -05:00
Kartikey Tanna
e0ec24e3c0 Added an example of logging 2020-07-06 23:32:55 +05:30
Kartikey Tanna
c25b77fb6b Added docs for client-side logger 2020-05-03 11:52:06 +05:30
aminamos
7bb0706f2c update from PR #36222 2020-02-12 13:31:43 -05:00
alkeshghorpade
aed448cc50 Typo fix of visbility. 2020-01-10 18:59:48 +05:30
Dino Maric
966d3a7bf2 Fix typo in ACa documentation [ci skip] 2019-10-28 11:09:22 -04:00
Javan Makhmali
55311b1596 Ensure @rails/actioncable package contains complete source
Action Cable's JavaScript library can optionally be imported as an ES6 module via `import { … } from "@rails/actioncable/src"`, but that module is broken in most of the releases published on npm:

```
ERROR in ./node_modules/@rails/actioncable/src/connection.js
Module not found: Error: Can't resolve './internal' in './node_modules/@rails/actioncable/src'
 @ ./node_modules/@rails/actioncable/src/connection.js
 @ ./node_modules/@rails/actioncable/src/index.js
```

Because `internal.js` was gitignored, it would only be included if the publisher happened to have it generated locally. Committing it to version control ensures that won't happen, and gives us better visibility into changes over time.

References:
- https://github.com/rails/rails/pull/34370
- c0368ad090b79c19300a4aa133bb188b2d9ab611
2019-08-15 09:19:59 -04:00
rmacklin
d03177ffbc Simplify ActionCable.createWebSocketURL and realphabetize exports (#35810)
* Remove unnecessary variable from ActionCable.createWebSocketURL

* Improve ActionCable test by creating the Consumer before reassigning URL

With this change, the test now actually verifies that the Consumer's url
property changes dynamically (from testURL to `${testURL}foo`).

* Fix alphabetization of ActionCable exports
2019-04-02 23:04:43 +02:00
Ryan Castner
6d488a22d3 feat(js): Dynamic ActionCable URL (#35579)
* Failing test case

* feat: Dynamic Url Generation

Change createWebSocketURL to be a closure that allows url to be evaluated at the time the webSocket is established

* refactor: createWebSocketURL to Consumer, remove need for closure

Move initial call to createWebSocketURL in createConsumer

* docs: Add documentation for dynamic url and string args to createConsumer

Co-Authored-By: rmacklin <rmacklin@users.noreply.github.com>

[Ryan Castner, rmacklin]
2019-03-31 19:41:12 +02:00
Kasper Timm Hansen
5f7e01c84c
Fix style issues and build source after #35525
Ran `cd actioncable && yarn build`.

[ Kasper Timm Hansen & Ryan Castner ]
2019-03-11 14:32:43 +01:00
Ryan Castner
9333f86adb
address pr feedback
change if statement to ternary, use const for consistency, add spacing after ternary expression
2019-03-09 14:55:54 -05:00
Ryan Castner
c7ca85ef31 feat(js): Dynamic Actioncable WebSocket URL
Allow createWebSocketURL fn to accept a function to generate the websocket URL rather than a string.
2019-03-07 22:14:20 -05:00
Richard Macklin
39493185d3 Remove explicit document receiver from add/removeEventListener calls
This allows ActionCable to be used in a web worker, where the `document`
global is undefined. Previously, attempting to use ActionCable inside a
web worker would result in this exception after you try to open a
connection:
```
ReferenceError: document is not defined
```

The visibilitychange event won't ever get triggered in a worker, so
adding the listener is effectively a no-op there. But the listener is
mainly a convenience, rather than a critical piece of the javascript
interface, so using ActionCable in a worker will still work. (And you
could listen for visibilitychange yourself in a window script, then tell
the worker to reconnect if you still want that behavior.)
2019-01-15 22:14:33 -08:00
Richard Macklin
ac8ffbe76a Replace window references in ActionCable with self
Before this change, attempting to use ActionCable inside a web worker
would result in an exception being thrown:
```
ReferenceError: window is not defined
```

By replacing the `window` reference with `self`, which is available in
both a window context and a worker context, we can avoid this error.

Ref:
https://developer.mozilla.org/en-US/docs/Web/API/Window/self
2019-01-14 17:44:35 -08:00
Richard Macklin
739f88e52e Simplify this.isActive() && this.webSocket into this.isActive()
in Connection#close. We can do this because `isActive()` can only
return `true` if `this.webSocket` is truthy. (We can't have an active
connection without having instantiated a WebSocket. This is confirmed
in the code: Connection#isActive calls Connection#isState which calls
Connection#getState, which checks if `this.webSocket` is truthy and
returns `null` otherwise.)
2019-01-14 11:52:46 -08:00
Richard Macklin
6320916513 Simplify ActionCable.getConfig, Connection#getProtocol, and Connection#close
by relying on the implicit undefined return value
2019-01-14 11:35:04 -08:00
Richard Macklin
dbe073aebf Simplify ActionCable.createConsumer by using default argument 2019-01-14 11:33:24 -08:00
Mick Staugaard
58dbc1c2ed Stop trying to reconnect on unauthorized cable connections 2018-12-05 10:40:29 -08:00
Richard Macklin
2bb4fdef5e Replace reference to WebSocket global with ActionCable.adapters.WebSocket
The WebSocket dependency of ActionCable.Connection was made configurable
in 66901c1849efae74c8a58fe0cb36afd487c067cc

However, the reference here in Connection#getState was not updated to
use the configurable property. This change remedies that and adds a test
to verify it. Additionally, it backfills a test to ensure that
Connection#open uses the configurable property.
2018-12-01 14:49:43 -08:00
rmacklin
aa1ba9cb24 Remove circular dependency warnings in ActionCable javascript and publish source modules with fine-grained exports (#34370)
* Replace several ActionCable.* references with finer-grained imports

This reduces the number of circular dependencies among the module
imports from 4:

```
(!) Circular dependency: app/javascript/action_cable/index.js -> app/javascript/action_cable/connection.js -> app/javascript/action_cable/index.js
(!) Circular dependency: app/javascript/action_cable/index.js -> app/javascript/action_cable/connection_monitor.js -> app/javascript/action_cable/index.js
(!) Circular dependency: app/javascript/action_cable/index.js -> app/javascript/action_cable/consumer.js -> app/javascript/action_cable/index.js
(!) Circular dependency: app/javascript/action_cable/index.js -> app/javascript/action_cable/subscriptions.js -> app/javascript/action_cable/index.js
```

to 2:

```
(!) Circular dependency: app/javascript/action_cable/index.js -> app/javascript/action_cable/connection.js -> app/javascript/action_cable/index.js
(!) Circular dependency: app/javascript/action_cable/index.js -> app/javascript/action_cable/connection.js -> app/javascript/action_cable/connection_monitor.js -> app/javascript/action_cable/index.js
```

* Remove tests that only test javascript object property assignment

These tests really only assert that you can assign a property to
the ActionCable global object. That's true for pretty much any object
in javascript (it would only be false if the object has been frozen, or
has explicitly set some properties to be nonconfigurable).

* Refactor ActionCable to provide individual named exports

By providing individual named exports rather than a default export which
is an object with all of those properties, we enable applications to
only import the functions they need: any unused functions will be
removed via tree shaking.

Additionally, this restructuring removes the remaining circular
dependencies by extracting the separate adapters and logger modules, so
there are now no warnings when compiling the ActionCable bundle.

Note: This produces two small breaking API changes:

- The `ActionCable.WebSocket` getter and setter would be moved to
  `ActionCable.adapters.WebSocket`. If a user is currently configuring
  this, when upgrading they'd need to either add a delegated
  getter/setter themselves, or change it like this:
   ```diff
   -    ActionCable.WebSocket = MyWebSocket
   +    ActionCable.adapters.WebSocket = MyWebSocket
    ```
   Applications which don't change the WebSocket adapter would not need
   any changes for this when upgrading.

- Similarly, the `ActionCable.logger` getter and setter would be moved
  to `ActionCable.adapters.logger`. If a user is currently configuring
  this, when upgrading they'd need to either add a delegated
  getter/setter themselves, or change it like this:
   ```diff
   -    ActionCable.logger = myLogger
   +    ActionCable.adapters.logger = myLogger
    ```
   Applications which don't change the logger would not need any changes
   for this when upgrading.

These two aspects of the public API have to change because there's no
way to export a property setter for `WebSocket` (or `logger`) such that
this:
```js
import ActionCable from "actioncable"

ActionCable.WebSocket = MyWebSocket
```
would actually update `adapters.WebSocket`. (We can only offer that if
we have two separate source files like if `index.js` uses
`import * as ActionCable from "./action_cable" and then exports a
wrapper which has delegated getters and setters for those properties.)

This API change is very minor - it should be easy for applications to
add the `adapters.` prefix in their assignments or to patch in delegated
setters. And especially because most applications in the wild are not
ever changing the default value of `ActionCable.WebSocket` or
`ActionCable.logger` (because the default values are perfect), this API
breakage is worth the tree-shaking benefits we gain.

* Include source code in published actioncable npm package

This allows actioncable users to ship smaller javascript bundles to
visitors using modern browsers, as demonstrated in this repository:
https://github.com/rmacklin/actioncable-es2015-build-example

In that example, the bundle shrinks by 2.8K (25.2%) when you simply
change the actioncable import to point to the untranspiled src.

If you go a step further, like this:
```
diff --git a/app/scripts/main.js b/app/scripts/main.js
index 17bc031..1a2b2e0 100644
--- a/app/scripts/main.js
+++ b/app/scripts/main.js
@@ -1,6 +1,6 @@
-import ActionCable from 'actioncable';
+import * as ActionCable from 'actioncable';

 let cable = ActionCable.createConsumer('wss://cable.example.com');

 cable.subscriptions.create('AppearanceChannel', {
```

then the bundle shrinks by 3.6K (31.7%)!

In addition to allowing smaller bundles for those who ship untranspiled
code to modern browsers, including the source code in the published
package can be useful in other ways:

1. Users can import individual modules rather than the whole library
2. As a result of (1), users can also monkey patch parts of actioncable
   by importing the relevant module, modifying the exported object, and
   then importing the rest of actioncable (which would then use the
   patched object).

Note: This is the same enhancement that we made to activestorage in
c0368ad090b79c19300a4aa133bb188b2d9ab611

* Remove unused commonjs & resolve plugins from ActionCable rollup config

These were added when we copied the rollup config from ActiveStorage,
but ActionCable does not have any commonjs dependencies (it doesn't have
any external dependencies at all), so these plugins are unnecessary here

* Change ActionCable.startDebugging() -> ActionCable.logger.enabled=true

and ActionCable.stopDebugging() -> ActionCable.logger.enabled=false

This API is simpler and more clearly describes what it does

* Change Travis configuration to run yarn install at the root for ActionCable builds

This is necessary now that the repository is using Yarn Workspaces
2018-12-01 16:25:02 -05:00
Richard Macklin
a4c27588d5 Synchronize ActionCable JS source code with compiled bundle
30a0c7e04093add0b14be6da17c7496e7dd40e10 commited changes to the
compiled bundle but not to the corresponding source files. This meant
that running `yarn build` was producing untracked changes to the
compiled bundle. The fix is to commit the changes to the source files
so that they are in sync.
2018-11-16 20:00:45 -08:00
Husam Bilal
30a0c7e040 Allow patching polling interval logarithmic multiplier 2018-11-14 11:30:47 +02:00
Richard Macklin
c96139af71 Convert ActionCable javascript to ES2015 modules with modern build environment
We've replaced the sprockets `//= require` directives with ES2015
imports. As a result, the ActionCable javascript can now be compiled
with rollup (like ActiveStorage already is).

- Rename action_cable/index.js.erb -> action_cable/index.js

- Add rake task to generate a javascript module of the ActionCable::INTERNAL ruby hash

  This will allow us to get rid of ERB from the actioncable javascript,
  since it is only used to interpolate ActionCable::INTERNAL.to_json.

- Import INTERNAL directly in ActionCable Connection module

  This is necessary to remove a load-order dependency conflict in the
  rollup-compiled build. Using ActionCable.INTERNAL would result in a
  runtime error:
  ```
  TypeError: Cannot read property 'INTERNAL' of undefined
  ```
  because ActionCable.INTERNAL is not set before the Connection module
  is executed.

  All other ActionCable.* references are executed inside of the body of a
  function, so there is no load-order dependency there.

- Add eslint and eslint-plugin-import devDependencies to actioncable

  These will be used to add a linting setup to actioncable like the one
  in activestorage.

- Add .eslintrc to actioncable

  This lint configuration was copied from activestorage

- Add lint script to actioncable

  This is the same as the lint script in activestorage

- Add babel-core, babel-plugin-external-helpers, and babel-preset-env devDependencies to actioncable

  These will be used to add ES2015 transpilation support to actioncable
  like we have in activestorage.

- Add .babelrc to actioncable

  This configuration was copied from activestorage

- Enable loose mode in ActionCable's babel config

  This generates a smaller bundle when compiled

- Add rollup devDependencies to actioncable

  These will be used to add a modern build pipeline to actioncable like
  the one in activestorage.

- Add rollup config to actioncable

  This is essentially the same as the rollup config from activestorage

- Add prebuild and build scripts to actioncable package

  These scripts were copied from activestorage

- Invoke code generation task as part of actioncable's prebuild script

  This will guarantee that the action_cable/internal.js module is
  available at build time (which is important, because two other modules
  now depend on it).

- Update actioncable package to reference the rollup-compiled files

  Now that we have a fully functional rollup pipeline in actioncable, we
  can use the compiled output in our npm package.

- Remove build section from ActionCable blade config

  Now that rollup is responsible for building ActionCable, we can remove
  that responsibility from Blade.

- Remove assets:compile and assets:verify tasks from ActionCable

  Now that we've added a compiled ActionCable bundle to version control,
  we don't need to compile and verify it at publish-time.

  (We're following the pattern set in ActiveStorage.)

- Include compiled ActionCable javascript bundle in published gem

  This is necessary to maintain support for depending on the ActionCable
  javascript through the Sprockets asset pipeline.

- Add compiled ActionCable bundle to version control

  This mirrors what we do in ActiveStorage, and allows ActionCable to
  continue to be consumed via the sprockets-based asset pipeline when
  using a git source instead of a published version of the gem.
2018-11-02 08:41:05 -07:00
Richard Macklin
0eb6b86e96 Refactor decaffeinate output to more natural/idiomatic javascript
- Remove unnecessary Array.from usages from subscriptions.js

  These were all Arrays before, so Array.from is a no-op

- Remove unnecessary IIFEs from subscriptions.js

- Manually decaffeinate sample ActionCable code in comments

  Here the coffeescript -> ES2015 conversion was done by hand rather than
  using decaffeinate, because these code samples were simple enough.

- Refactor ActionCable.Subscription to avoid initClass

- Refactor ActionCable.Subscription to use ES2015 default parameters

- Refactor ActionCable.ConnectionMonitor to avoid initClass

- Refactor ActionCable.ConnectionMonitor to use shorter variations of null checks

- Remove unnecessary code created because of implicit returns in ConnectionMonitor

  This removes the `return` statements that were returning the value of
  console.log and those from private methods whose return value was not
  being used.

- Refactor ActionCable.Connection to avoid initClass

- Refactor Connection#isProtocolSupported and #isState

  This addresses these three decaffeinate cleanup suggestions:
  - DS101: Remove unnecessary use of Array.from
  - DS104: Avoid inline assignments
  - DS204: Change includes calls to have a more natural evaluation order

  It also removes the use of Array.prototype.includes, which means we
  don't have to worry about providing a polyfill or requiring that end
  users provide one.

- Refactor ActionCable.Connection to use ES2015 default parameters

- Refactor ActionCable.Connection to use shorter variations of null checks

- Remove return statements that return the value of console.log() in ActionCable.Connection

- Simplify complex destructure assignment in connection.js

  decaffeinate had inserted
  ```
  adjustedLength = Math.max(protocols.length, 1)
  ```
  to be safe, but we know that there has to always be at least one
  protocol, so we don't have to worry about protocols.length being 0 here.

- Refactor Connection#getState

  The decaffeinate translation of this method was not very clear, so we've
  rewritten it to be more natural.

- Simplify destructure assignment in connection.js

- Remove unnecessary use of Array.from from action_cable.js.erb

- Refactor ActionCable#createConsumer and #getConfig

  This addresses these two decaffeinate cleanup suggestions:
  - DS104: Avoid inline assignments
  - DS207: Consider shorter variations of null checks

- Remove unnecessary code created because of implicit returns in action_cable.js.erb

  This removes the `return` statements that were returning the value of
  console.log and those from methods that just set and unset the
  `debugging` flag.

- Remove decaffeinate suggestion about avoiding top-level this

  In this case, the top-level `this` is intentional, so it's okay to
  ignore this suggestion.

- Remove decaffeinate suggestions about removing unnecessary returns

  I did remove some of the return statements in previous commits, where
  it seemed appropriate. However, the rest of these should probably remain
  because the return values have been exposed through the public API. If
  we want to break that contract, we can do so, but I think it should be
  done deliberately as part of a breaking-API change (separate from this
  coffeescript -> ES2015 conversion)

- Remove unused `unsupportedProtocol` variable from connection.js

  Leaving this would cause eslint to fail

- Refactor Subscriptions methods to avoid `for` ... `of` syntax

  Babel transpiles `for` ... `of` syntax to use `Symbol.iterator`, which
  would require a polyfill in applications that support older browsers.

  The `for` ... `of` syntax was produced by running `decaffeinate`, but in
  these instances a simpler `map` should be sufficient and avoid any
  `Symbol` issues.
2018-11-02 08:40:59 -07:00
Richard Macklin
403c001c56 Run decaffeinate on action_cable/*.js
Using [decaffeinate], we have converted these files from coffeescript
syntax to ES2015 syntax. Decaffeinate is very conservative in the
conversion process to ensure exact coffeescript semantics are preserved.
Most of the time, it's safe to clean up the code, and decaffeinate has
left suggestions regarding potential cleanups we can take. I'll tackle
those cleanups separately.

After running decaffeinate, I ran:
```
eslint --fix app/javascript
```
using the eslint configuration from ActiveStorage to automatically
correct lint violations in the decaffeinated output. This removed 189
extra semicolons and changed one instance of single quotes to double
quotes.

Note: decaffeinate and eslint can't parse ERB syntax. So I worked around
that by temporarily quoting the ERB:
```diff
 @ActionCable =
-  INTERNAL: <%= ActionCable::INTERNAL.to_json %>
+  INTERNAL: "<%= ActionCable::INTERNAL.to_json %>"
   WebSocket: window.WebSocket
   logger: window.console
```
and then removing those quotes after running decaffeinate and eslint.

[decaffeinate]: https://github.com/decaffeinate/decaffeinate
2018-11-02 08:40:35 -07:00
Richard Macklin
7b0b37240a Move actioncable javascript to app/javascript and change .coffee -> .js
- Rename action_cable/*.coffee -> *.js

- Move app/assets/javascripts/* -> app/javascript/*

- Rename action_cable.js.erb -> action_cable/index.js.erb

Renaming the extension to .js is in preparation for converting these
files from coffeescript to ES2015.

Moving the files to app/javascript and putting the entry point in
index.js.erb changes the structure of ActionCable's javascript to match
the structure of ActiveStorage's javascript.

(We are doing the file moving and renaming in a separate commit to
ensure that the git history of the files will be preserved - i.e. git
will track these as file renames rather than unrelated file
additions/deletions. In particular, git blame will still trace back to
the original authorship.)
2018-11-02 08:40:10 -07:00
Duncan Grazier
23e3e2bc2b ActionCable should not raise when a connection is already open
ActionCable was throwing a "Existing connection must be closed before
opening" exception which was being picked up as a production issue in
our error monitoring software. Since this happens pretty often on any
device that allows the browser to sleep (mobile) this error was getting
triggered often.

This change removes the exception, but keeps logging the occurrence. We
now return `false` to let the caller now that `open` failed.
2017-01-06 12:49:58 -05:00
Jon Moss
66901c1849 Add configuration for WebSocket and logger
[Javan Makhmali, Jon Moss]
2016-05-31 13:06:08 -04:00
Javan Makhmali
11078dddbb Build action_cable.js with Blade 2016-05-24 13:11:10 -04:00
Jon Moss
548c1d6e8b
Publish Action Cable to NPM when we release.
Signed-off-by: Jeremy Daer <jeremydaer@gmail.com>
2016-05-11 19:36:27 -07:00
Jeremy Daer
9c2945f4cc Cable typo: isSupportedProtocol -> isProtocolSupported 2016-04-05 21:56:59 -07:00
Jeremy Daer
fa3537506a Merge pull request #24224 from danielrhodes/actioncable-websocket-protocols
ActionCable protocol negotiation
2016-04-05 09:26:11 -07:00
Daniel Rhodes
cbd15da027 Added protocol negotiation
This is primarily for backwards compatibility for when
or if the protocol is changed in future versions.

If the server fails to respond with an acceptable
protocol, the client disconnects and disables
the monitor.
2016-04-05 15:55:59 +02:00
Jon Evans
ff5f1d33fc Fix WebSocket already open log message typo 2016-03-22 12:55:37 -06:00
Javan Makhmali
1d5f80c758 Return subscription object(s) when updating the collection 2016-03-04 10:34:24 -05:00
Pratik Naik
9ce6fe439a Make sure ActionCable.Subscriptions#create always returns the newly created subscription object 2016-03-04 09:30:15 -06:00
Javan Makhmali
3e4ecbe8e6 Store reference to Subscriptions instance for convenience 2016-03-03 21:44:11 -05:00
Javan Makhmali
f1c93ed828 Implicity add Subscription instance to subscriptions collection 2016-03-03 21:40:16 -05:00