websocket-rails 0.6.2 → 0.7.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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +32 -0
  3. data/Gemfile +2 -1
  4. data/README.md +29 -34
  5. data/lib/assets/javascripts/websocket_rails/abstract_connection.js.coffee +45 -0
  6. data/lib/assets/javascripts/websocket_rails/channel.js.coffee +34 -17
  7. data/lib/assets/javascripts/websocket_rails/event.js.coffee +13 -11
  8. data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +44 -45
  9. data/lib/assets/javascripts/websocket_rails/main.js +1 -0
  10. data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +20 -34
  11. data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +60 -15
  12. data/lib/generators/websocket_rails/install/templates/websocket_rails.rb +15 -0
  13. data/lib/rails/config/routes.rb +1 -1
  14. data/lib/rails/tasks/websocket_rails.tasks +6 -2
  15. data/lib/websocket_rails/channel.rb +28 -2
  16. data/lib/websocket_rails/channel_manager.rb +16 -0
  17. data/lib/websocket_rails/configuration.rb +26 -1
  18. data/lib/websocket_rails/connection_adapters/http.rb +7 -0
  19. data/lib/websocket_rails/connection_adapters/web_socket.rb +3 -1
  20. data/lib/websocket_rails/connection_manager.rb +1 -1
  21. data/lib/websocket_rails/controller_factory.rb +1 -1
  22. data/lib/websocket_rails/event.rb +9 -2
  23. data/lib/websocket_rails/logging.rb +0 -1
  24. data/lib/websocket_rails/synchronization.rb +11 -7
  25. data/lib/websocket_rails/version.rb +1 -1
  26. data/spec/javascripts/generated/assets/abstract_connection.js +71 -0
  27. data/spec/javascripts/generated/assets/channel.js +58 -34
  28. data/spec/javascripts/generated/assets/event.js +12 -16
  29. data/spec/javascripts/generated/assets/http_connection.js +67 -65
  30. data/spec/javascripts/generated/assets/websocket_connection.js +36 -51
  31. data/spec/javascripts/generated/assets/websocket_rails.js +68 -21
  32. data/spec/javascripts/generated/specs/channel_spec.js +102 -19
  33. data/spec/javascripts/generated/specs/helpers.js +17 -0
  34. data/spec/javascripts/generated/specs/websocket_connection_spec.js +72 -19
  35. data/spec/javascripts/generated/specs/websocket_rails_spec.js +146 -47
  36. data/spec/javascripts/support/jasmine.yml +10 -2
  37. data/spec/javascripts/support/jasmine_helper.rb +38 -0
  38. data/spec/javascripts/websocket_rails/channel_spec.coffee +66 -12
  39. data/spec/javascripts/websocket_rails/event_spec.coffee +7 -7
  40. data/spec/javascripts/websocket_rails/helpers.coffee +6 -0
  41. data/spec/javascripts/websocket_rails/websocket_connection_spec.coffee +53 -15
  42. data/spec/javascripts/websocket_rails/websocket_rails_spec.coffee +108 -25
  43. data/spec/unit/base_controller_spec.rb +41 -0
  44. data/spec/unit/channel_manager_spec.rb +21 -0
  45. data/spec/unit/channel_spec.rb +43 -3
  46. data/spec/unit/connection_adapters/http_spec.rb +24 -3
  47. data/spec/unit/connection_adapters_spec.rb +2 -2
  48. data/spec/unit/connection_manager_spec.rb +1 -1
  49. data/spec/unit/event_spec.rb +25 -1
  50. data/spec/unit/logging_spec.rb +1 -1
  51. metadata +57 -67
  52. data/spec/javascripts/support/jasmine_config.rb +0 -63
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2f431734036d380cfcb865a9db8dd0cb57a8b0e0
4
+ data.tar.gz: 5c68a9bd3f5bffd6ba001521f914c7118613e5f3
5
+ SHA512:
6
+ metadata.gz: 3171366f6a8d400adcfd0b5bcf83baed9abe8d34985122503f49b698002a8842ff5bde5cdd5d4c5b35c39056e01bc8f8a46c812d7cbd4eaa51ffc11c330ffc20
7
+ data.tar.gz: dd0eddf5584f3a22e2f30fd207c83f7355e0ca5351577aedbf074efa597c278fb117d673d308abcbc9bf904a3ccfd5f9a67c4034df386027b110a218c7a9f151
@@ -1,5 +1,37 @@
1
1
  # WebsocketRails Change Log
2
2
 
3
+ ## Version 0.7.0
4
+
5
+ March 14 2014
6
+
7
+ * Add verification of parsing results in Event. (Prevents a possible
8
+ denial of service attack when sending improperly formatted but valid
9
+ JSON. Thanks to @maharifu
10
+
11
+ * Support HTTP streaming for Internet Explorer versions 8+ by using
12
+ XDomainRequest - Thanks to @lkol
13
+
14
+ * Added a possibility to set channel success and failure callbacks on
15
+ subscribe. - Thanks to @lkol
16
+
17
+ * Rescue symbolizing of channel names. fixes #166 - Thanks to @KazW
18
+
19
+ * Refactor *.coffee files. Add reconnect() method. - Thanks to @jtomaszewski
20
+
21
+ * Add Channel tokens to prevent unauthorized subscriptions to channels.
22
+ Thanks - @moaa and @elthariel
23
+
24
+ * Fixed a bug where a newline was being outputted in the log regardless of log level - Thanks to @markmalek
25
+
26
+ * Properly handle WSS and WS protocols in the JavaScript client - Thanks
27
+ to @markee
28
+
29
+ * Defer #on_open to EM.next_tick. fixes #135 - Thanks to @moaa
30
+
31
+ * Add subscriber Join/Part events for channels - Thanks to @moaa
32
+
33
+ * Convert controller's `action_name` to a string to get AbstractController::Callbacks (`before_action`) working properly [fixes #150] - Thanks to @Pitr
34
+
3
35
  ## Version 0.6.2
4
36
 
5
37
  September 8 2013
data/Gemfile CHANGED
@@ -2,11 +2,12 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "rspec-rails", ">=2.12.0"
5
+ gem "rspec-rails", ">=2.14.0"
6
6
  gem "therubyrhino"
7
7
  gem "therubyracer"
8
8
  gem "jasmine"
9
9
  gem "headless"
10
+ gem "selenium-webdriver"
10
11
  gem "coffee-script"
11
12
  gem "thin"
12
13
  gem "eventmachine"
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Websocket-Rails
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/DanKnox/websocket-rails.png)](https://secure.travis-ci.org/DanKnox/websocket-rails)
3
+ [![Build Status](https://travis-ci.org/websocket-rails/websocket-rails.png?branch=master)](https://travis-ci.org/websocket-rails/websocket-rails)
4
4
 
5
- If you haven't done so yet, check out the [Project Page](http://danknox.github.com/websocket-rails/) to get a feel for the project direction. Feedback is very much appreciated. Post an issue on the issue tracker or [shoot us an email](mailto:support@threedotloft.com) to give us your thoughts.
5
+ If you haven't done so yet, check out the [Project
6
+ Page](http://websocket-rails.github.io) to get a feel for the project direction. Feedback is very much appreciated. Post an issue on the issue tracker or [shoot us an email](mailto:support@threedotloft.com) to give us your thoughts.
6
7
 
7
8
  **Find us on IRC #websocket-rails**
8
9
 
@@ -11,17 +12,10 @@ questions.
11
12
 
12
13
  ## Recent Updates
13
14
 
14
- Check out the [CHANGELOG](https://github.com/DanKnox/websocket-rails/blob/master/CHANGELOG.md) to find out what's new.
15
+ Check out the [CHANGELOG](https://github.com/websocket-rails/websocket-rails/blob/master/CHANGELOG.md) to find out what's new.
15
16
 
16
17
  As of version 0.2.0, non event machine based web servers such as Phusion
17
- Passenger are supported through the use of the [Standalone Server Mode](https://github.com/DanKnox/websocket-rails/wiki/Standalone-Server-Mode).
18
-
19
- **Note About Development**
20
-
21
- I am currently seeking a co-maintainer for this project. My time has
22
- been limited recently and I have not been as attentive to issues and
23
- feature requests as I would like. If you are interested in helping out
24
- please send me an email or post a message on the issue tracker.
18
+ Passenger are supported through the use of the [Standalone Server Mode](https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode).
25
19
 
26
20
  ## Overview
27
21
 
@@ -33,23 +27,21 @@ just about any browser with Flash sockets.
33
27
 
34
28
  ## Installation and Usage Guides
35
29
 
36
- Check out the [Example Application](https://github.com/DanKnox/websocket-rails-Example-Project) for an example implementation.
37
-
38
30
  * [Installation
39
- Guide](https://github.com/DanKnox/websocket-rails/wiki/Installation-and-Setup)
31
+ Guide](https://github.com/websocket-rails/websocket-rails/wiki/Installation-and-Setup)
40
32
  * [Event
41
- Router](https://github.com/DanKnox/websocket-rails/wiki/The-Event-Router)
42
- * [WebsocketRails Controllers](https://github.com/DanKnox/websocket-rails/wiki/WebsocketRails Controllers)
33
+ Router](https://github.com/websocket-rails/websocket-rails/wiki/The-Event-Router)
34
+ * [WebsocketRails Controllers](https://github.com/websocket-rails/websocket-rails/wiki/WebsocketRails Controllers)
43
35
  * [Using the JavaScript
44
- Client](https://github.com/DanKnox/websocket-rails/wiki/Using-the-JavaScript-Client)
36
+ Client](https://github.com/websocket-rails/websocket-rails/wiki/Using-the-JavaScript-Client)
45
37
  * [Using
46
- Channels](https://github.com/DanKnox/websocket-rails/wiki/Working-with-Channels)
47
- * [Using Private Channels](https://github.com/DanKnox/websocket-rails/wiki/Using-Private-Channels)
38
+ Channels](https://github.com/websocket-rails/websocket-rails/wiki/Working-with-Channels)
39
+ * [Using Private Channels](https://github.com/websocket-rails/websocket-rails/wiki/Using-Private-Channels)
48
40
  * [The
49
- DataStore](https://github.com/DanKnox/websocket-rails/wiki/Using-the-DataStore)
50
- * [Reloading Controllers In Development](https://github.com/DanKnox/websocket-rails/wiki/Reloading-Controllers-In-Development)
51
- * [Multiple Servers and Background Jobs](https://github.com/DanKnox/websocket-rails/wiki/Multiple-Servers-and-Background-Jobs)
52
- * [Standalone Server Mode](https://github.com/DanKnox/websocket-rails/wiki/Standalone-Server-Mode)
41
+ DataStore](https://github.com/websocket-rails/websocket-rails/wiki/Using-the-DataStore)
42
+ * [Reloading Controllers In Development](https://github.com/websocket-rails/websocket-rails/wiki/Reloading-Controllers-In-Development)
43
+ * [Multiple Servers and Background Jobs](https://github.com/websocket-rails/websocket-rails/wiki/Multiple-Servers-and-Background-Jobs)
44
+ * [Standalone Server Mode](https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode)
53
45
 
54
46
  ## Handle Events With Class
55
47
 
@@ -211,23 +203,26 @@ WebsocketRails[:secret_posts].make_private
211
203
  On the client side, you can use the `dispatcher.subscribe_private()`
212
204
  method to subscribe to a private channel.
213
205
 
214
- Read the [Private Channel Wiki](https://github.com/DanKnox/websocket-rails/wiki/Using-Private-Channels) for more information on subscribing to
215
- private channels from the JavaScript client and handling the
216
- authorization in your controller.
206
+ Read the [Private Channel Wiki](https://github.com/websocket-rails/websocket-rails/wiki/Using-Private-Channels) for more information on subscribing to private channels from the JavaScript client and handling the authorization in your controller.
217
207
 
218
208
  ## Credit where credit is due
219
209
 
220
- Big thanks to our
221
- [contributors](https://github.com/DanKnox/websocket-rails/graphs/contributors)
222
- who have helped keep this project moving.
210
+ Big thanks to our [contributors](https://github.com/websocket-rails/websocket-rails/graphs/contributors) who have helped keep this project moving.
223
211
 
224
- Special thanks to [@nessche](https://github.com/nessche) who provided the improved routing DSL and
225
- RSpec matcher suite.
212
+ Special thanks to [@nessche](https://github.com/nessche) who provided the improved routing DSL and RSpec matcher suite.
213
+
214
+ The `websocket-rails` organization logo was kindly provided by [Uken Games](http://www.uken.com/).
226
215
 
227
216
  ## Development
228
217
 
229
- This gem is created and maintained by Dan Knox and Kyle Whalen under the MIT License.
218
+ Please check out the [Development Guide](https://github.com/websocket-rails/websocket-rails/wiki/Development) if you are interested in contributing. It should cover everything you need to get up and running.
219
+
220
+ ## Core Team
221
+
222
+ The current `websocket-rails` core team consists of the following individuals:
230
223
 
231
- Brought to you by:
224
+ * [@DanKnox](https://github.com/DanKnox)
225
+ * [@Pitr](https://github.com/pitr)
226
+ * [@moaa](https://github.com/moaa)
232
227
 
233
- Three Dot Loft LLC
228
+ New contributors and pull requests are always welcome.
@@ -0,0 +1,45 @@
1
+ ###
2
+ Abstract Interface for the WebSocketRails client.
3
+ ###
4
+ class WebSocketRails.AbstractConnection
5
+
6
+ constructor: (url, @dispatcher) ->
7
+ @message_queue = []
8
+
9
+ close: ->
10
+
11
+ trigger: (event) ->
12
+ if @dispatcher.state != 'connected'
13
+ @message_queue.push event
14
+ else
15
+ @send_event event
16
+
17
+ send_event: (event) ->
18
+ # Events queued before connecting do not have the correct
19
+ # connection_id set yet. We need to update it before dispatching.
20
+ event.connection_id = @connection_id if @connection_id?
21
+
22
+ # ...
23
+
24
+ on_close: (event) ->
25
+ if @dispatcher && @dispatcher._conn == @
26
+ close_event = new WebSocketRails.Event(['connection_closed', event])
27
+ @dispatcher.state = 'disconnected'
28
+ @dispatcher.dispatch close_event
29
+
30
+ on_error: (event) ->
31
+ if @dispatcher && @dispatcher._conn == @
32
+ error_event = new WebSocketRails.Event(['connection_error', event])
33
+ @dispatcher.state = 'disconnected'
34
+ @dispatcher.dispatch error_event
35
+
36
+ on_message: (event_data) ->
37
+ if @dispatcher && @dispatcher._conn == @
38
+ @dispatcher.new_message event_data
39
+
40
+ setConnectionId: (@connection_id) ->
41
+
42
+ flush_queue: ->
43
+ for event in @message_queue
44
+ @trigger event
45
+ @message_queue = []
@@ -9,39 +9,56 @@ For instance:
9
9
  ###
10
10
  class WebSocketRails.Channel
11
11
 
12
- constructor: (@name,@_dispatcher,@is_private) ->
12
+ constructor: (@name, @_dispatcher, @is_private = false, @on_success, @on_failure) ->
13
+ @_callbacks = {}
14
+ @_token = undefined
15
+ @_queue = []
13
16
  if @is_private
14
17
  event_name = 'websocket_rails.subscribe_private'
15
18
  else
16
19
  event_name = 'websocket_rails.subscribe'
17
20
 
18
- event = new WebSocketRails.Event( [event_name, {data: {channel: @name}},@_dispatcher.connection_id], @_success_launcher, @_failure_launcher)
21
+ @connection_id = @_dispatcher._conn?.connection_id
22
+ event = new WebSocketRails.Event( [event_name, {data: {channel: @name}}, @connection_id], @_success_launcher, @_failure_launcher)
19
23
  @_dispatcher.trigger_event event
20
- @_callbacks = {}
21
24
 
22
- destroy: () =>
23
- event_name = 'websocket_rails.unsubscribe'
24
- event = new WebSocketRails.Event( [event_name, {data: {channel: @name}}, @_dispatcher.connection_id] )
25
- @_dispatcher.trigger_event event
25
+ destroy: ->
26
+ if @connection_id == @_dispatcher._conn?.connection_id
27
+ event_name = 'websocket_rails.unsubscribe'
28
+ event = new WebSocketRails.Event( [event_name, {data: {channel: @name}}, @connection_id] )
29
+ @_dispatcher.trigger_event event
26
30
  @_callbacks = {}
27
31
 
28
- bind: (event_name, callback) =>
32
+ bind: (event_name, callback) ->
29
33
  @_callbacks[event_name] ?= []
30
34
  @_callbacks[event_name].push callback
31
35
 
32
- trigger: (event_name, message) =>
33
- event = new WebSocketRails.Event( [event_name, {channel: @name, data: message}, @_dispatcher.connection_id] )
34
- @_dispatcher.trigger_event event
36
+ trigger: (event_name, message) ->
37
+ event = new WebSocketRails.Event( [event_name, {channel: @name, data: message, token: @_token}, @connection_id] )
38
+ if !@_token
39
+ @_queue.push event
40
+ else
41
+ @_dispatcher.trigger_event event
42
+
43
+ dispatch: (event_name, message) ->
44
+ if event_name == 'websocket_rails.channel_token'
45
+ @connection_id = @_dispatcher._conn?.connection_id
46
+ @_token = message['token']
47
+ @flush_queue()
48
+ else
49
+ return unless @_callbacks[event_name]?
50
+ for callback in @_callbacks[event_name]
51
+ callback message
35
52
 
36
- dispatch: (event_name, message) =>
37
- return unless @_callbacks[event_name]?
38
- for callback in @_callbacks[event_name]
39
- callback message
40
-
41
53
  # using this method because @on_success will not be defined when the constructor is executed
42
54
  _success_launcher: (data) =>
43
55
  @on_success(data) if @on_success?
44
-
56
+
45
57
  # using this method because @on_failure will not be defined when the constructor is executed
46
58
  _failure_launcher: (data) =>
47
59
  @on_failure(data) if @on_failure?
60
+
61
+ flush_queue: ->
62
+ for event in @_queue
63
+ @_dispatcher.trigger_event event
64
+ @_queue = []
@@ -4,37 +4,39 @@ The Event object stores all the relevant event information.
4
4
 
5
5
  class WebSocketRails.Event
6
6
 
7
- constructor: (data,@success_callback,@failure_callback) ->
7
+ constructor: (data, @success_callback, @failure_callback) ->
8
8
  @name = data[0]
9
9
  attr = data[1]
10
10
  if attr?
11
11
  @id = if attr['id']? then attr['id'] else (((1+Math.random())*0x10000)|0)
12
12
  @channel = if attr.channel? then attr.channel
13
13
  @data = if attr.data? then attr.data else attr
14
+ @token = if attr.token? then attr.token
14
15
  @connection_id = data[2]
15
16
  if attr.success?
16
17
  @result = true
17
18
  @success = attr.success
18
19
 
19
- is_channel: =>
20
+ is_channel: ->
20
21
  @channel?
21
22
 
22
- is_result: =>
23
- @result == true
23
+ is_result: ->
24
+ typeof @result != 'undefined'
24
25
 
25
- is_ping: =>
26
+ is_ping: ->
26
27
  @name == 'websocket_rails.ping'
27
28
 
28
- serialize: =>
29
+ serialize: ->
29
30
  JSON.stringify [@name, @attributes()]
30
31
 
31
- attributes: =>
32
+ attributes: ->
32
33
  id: @id,
33
34
  channel: @channel,
34
35
  data: @data
36
+ token: @token
35
37
 
36
- run_callbacks: (success,data) =>
37
- if success == true
38
- @success_callback?(data)
38
+ run_callbacks: (@success, @result) ->
39
+ if @success == true
40
+ @success_callback?(@result)
39
41
  else
40
- @failure_callback?(data)
42
+ @failure_callback?(@result)
@@ -1,67 +1,66 @@
1
1
  ###
2
2
  HTTP Interface for the WebSocketRails client.
3
3
  ###
4
- class WebSocketRails.HttpConnection
5
- httpFactories: -> [
4
+ class WebSocketRails.HttpConnection extends WebSocketRails.AbstractConnection
5
+ connection_type: 'http'
6
+
7
+ _httpFactories: -> [
8
+ -> new XDomainRequest(),
6
9
  -> new XMLHttpRequest(),
7
10
  -> new ActiveXObject("Msxml2.XMLHTTP"),
8
11
  -> new ActiveXObject("Msxml3.XMLHTTP"),
9
12
  -> new ActiveXObject("Microsoft.XMLHTTP")
10
13
  ]
11
14
 
12
- createXMLHttpObject: =>
13
- xmlhttp = false
14
- factories = @httpFactories()
15
- for factory in factories
16
- try
17
- xmlhttp = factory()
18
- catch e
19
- continue
20
- break
21
- xmlhttp
22
-
23
- constructor: (@url, @dispatcher) ->
24
- @_url = @url
25
- @_conn = @createXMLHttpObject()
15
+ constructor: (url, @dispatcher) ->
16
+ super
17
+ @_url = "http://#{url}"
18
+ @_conn = @_createXMLHttpObject()
26
19
  @last_pos = 0
27
- @message_queue = []
28
- @_conn.onreadystatechange = @parse_stream
29
- @_conn.addEventListener("load", @connectionClosed, false)
20
+ try
21
+ @_conn.onreadystatechange = => @_parse_stream()
22
+ @_conn.addEventListener("load", @on_close, false)
23
+ catch e
24
+ @_conn.onprogress = => @_parse_stream()
25
+ @_conn.onload = @on_close
26
+ # set this as 3 always for parse_stream as the object does not have this property at all
27
+ @_conn.readyState = 3
30
28
  @_conn.open "GET", @_url, true
31
29
  @_conn.send()
32
30
 
33
- parse_stream: =>
34
- if @_conn.readyState == 3
35
- data = @_conn.responseText.substring @last_pos
36
- @last_pos = @_conn.responseText.length
37
- data = data.replace( /\]\]\[\[/g, "],[" )
38
- decoded_data = JSON.parse data
39
- @dispatcher.new_message decoded_data
31
+ close: ->
32
+ @_conn.abort()
40
33
 
41
- trigger: (event) =>
42
- if @dispatcher.state != 'connected'
43
- @message_queue.push event
44
- else
45
- @post_data @dispatcher.connection_id, event.serialize()
34
+ send_event: (event) ->
35
+ super
36
+ @_post_data event.serialize()
46
37
 
47
- post_data: (connection_id, payload) ->
38
+ _post_data: (payload) ->
48
39
  $.ajax @_url,
49
40
  type: 'POST'
50
41
  data:
51
- client_id: connection_id
42
+ client_id: @connection_id
52
43
  data: payload
53
44
  success: ->
54
45
 
55
- flush_queue: (connection_id) =>
56
- for event in @message_queue
57
- # Events queued before connecting do not have the correct
58
- # connection_id set yet. We need to update it before dispatching.
59
- if connection_id?
60
- event.connection_id = @dispatcher.connection_id
61
- @trigger event
62
- @message_queue = []
46
+ _createXMLHttpObject: ->
47
+ xmlhttp = false
48
+ factories = @_httpFactories()
49
+ for factory in factories
50
+ try
51
+ xmlhttp = factory()
52
+ catch e
53
+ continue
54
+ break
55
+ xmlhttp
63
56
 
64
- connectionClosed: (event) =>
65
- close_event = new WebSocketRails.Event(['connection_closed', event])
66
- @dispatcher.state = 'disconnected'
67
- @dispatcher.dispatch close_event
57
+ _parse_stream: ->
58
+ if @_conn.readyState == 3
59
+ data = @_conn.responseText.substring @last_pos
60
+ @last_pos = @_conn.responseText.length
61
+ data = data.replace( /\]\]\[\[/g, "],[" )
62
+ try
63
+ event_data = JSON.parse data
64
+ @on_message(event_data)
65
+ catch e
66
+ # just ignore if it cannot be parsed, probably whitespace
@@ -1,5 +1,6 @@
1
1
  //= require ./websocket_rails
2
2
  //= require ./event
3
+ //= require ./abstract_connection
3
4
  //= require ./http_connection
4
5
  //= require ./websocket_connection
5
6
  //= require ./channel