wwl-websocket-rails 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +328 -0
  3. data/Gemfile +27 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +239 -0
  6. data/Rakefile +72 -0
  7. data/bin/thin-socketrails +45 -0
  8. data/lib/assets/javascripts/websocket_rails/abstract_connection.js.coffee +45 -0
  9. data/lib/assets/javascripts/websocket_rails/channel.js.coffee +70 -0
  10. data/lib/assets/javascripts/websocket_rails/event.js.coffee +46 -0
  11. data/lib/assets/javascripts/websocket_rails/http_connection.js.coffee +66 -0
  12. data/lib/assets/javascripts/websocket_rails/main.js +6 -0
  13. data/lib/assets/javascripts/websocket_rails/websocket_connection.js.coffee +29 -0
  14. data/lib/assets/javascripts/websocket_rails/websocket_rails.js.coffee +158 -0
  15. data/lib/config.ru +3 -0
  16. data/lib/generators/websocket_rails/install/install_generator.rb +33 -0
  17. data/lib/generators/websocket_rails/install/templates/events.rb +14 -0
  18. data/lib/generators/websocket_rails/install/templates/websocket_rails.rb +68 -0
  19. data/lib/rails/app/controllers/websocket_rails/delegation_controller.rb +13 -0
  20. data/lib/rails/config/routes.rb +7 -0
  21. data/lib/rails/tasks/websocket_rails.tasks +42 -0
  22. data/lib/spec_helpers/matchers/route_matchers.rb +65 -0
  23. data/lib/spec_helpers/matchers/trigger_matchers.rb +138 -0
  24. data/lib/spec_helpers/spec_helper_event.rb +34 -0
  25. data/lib/websocket-rails.rb +108 -0
  26. data/lib/websocket_rails/base_controller.rb +208 -0
  27. data/lib/websocket_rails/channel.rb +97 -0
  28. data/lib/websocket_rails/channel_manager.rb +55 -0
  29. data/lib/websocket_rails/configuration.rb +177 -0
  30. data/lib/websocket_rails/connection_adapters/http.rb +120 -0
  31. data/lib/websocket_rails/connection_adapters/web_socket.rb +35 -0
  32. data/lib/websocket_rails/connection_adapters.rb +195 -0
  33. data/lib/websocket_rails/connection_manager.rb +119 -0
  34. data/lib/websocket_rails/controller_factory.rb +80 -0
  35. data/lib/websocket_rails/data_store.rb +145 -0
  36. data/lib/websocket_rails/dispatcher.rb +129 -0
  37. data/lib/websocket_rails/engine.rb +26 -0
  38. data/lib/websocket_rails/event.rb +193 -0
  39. data/lib/websocket_rails/event_map.rb +184 -0
  40. data/lib/websocket_rails/event_queue.rb +33 -0
  41. data/lib/websocket_rails/internal_events.rb +37 -0
  42. data/lib/websocket_rails/logging.rb +133 -0
  43. data/lib/websocket_rails/spec_helpers.rb +3 -0
  44. data/lib/websocket_rails/synchronization.rb +178 -0
  45. data/lib/websocket_rails/user_manager.rb +276 -0
  46. data/lib/websocket_rails/version.rb +3 -0
  47. data/spec/dummy/Rakefile +7 -0
  48. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  49. data/spec/dummy/app/controllers/chat_controller.rb +53 -0
  50. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  51. data/spec/dummy/app/models/user.rb +2 -0
  52. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  53. data/spec/dummy/config/application.rb +45 -0
  54. data/spec/dummy/config/boot.rb +10 -0
  55. data/spec/dummy/config/database.yml +22 -0
  56. data/spec/dummy/config/environment.rb +5 -0
  57. data/spec/dummy/config/environments/development.rb +26 -0
  58. data/spec/dummy/config/environments/production.rb +49 -0
  59. data/spec/dummy/config/environments/test.rb +34 -0
  60. data/spec/dummy/config/events.rb +7 -0
  61. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  62. data/spec/dummy/config/initializers/inflections.rb +10 -0
  63. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  64. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  65. data/spec/dummy/config/initializers/session_store.rb +8 -0
  66. data/spec/dummy/config/locales/en.yml +5 -0
  67. data/spec/dummy/config/routes.rb +58 -0
  68. data/spec/dummy/config.ru +4 -0
  69. data/spec/dummy/db/development.sqlite3 +0 -0
  70. data/spec/dummy/db/migrate/20130902222552_create_users.rb +10 -0
  71. data/spec/dummy/db/schema.rb +23 -0
  72. data/spec/dummy/db/test.sqlite3 +0 -0
  73. data/spec/dummy/log/development.log +17 -0
  74. data/spec/dummy/log/production.log +0 -0
  75. data/spec/dummy/log/server.log +0 -0
  76. data/spec/dummy/log/test.log +0 -0
  77. data/spec/dummy/public/404.html +26 -0
  78. data/spec/dummy/public/422.html +26 -0
  79. data/spec/dummy/public/500.html +26 -0
  80. data/spec/dummy/public/favicon.ico +0 -0
  81. data/spec/dummy/public/javascripts/application.js +2 -0
  82. data/spec/dummy/public/javascripts/controls.js +965 -0
  83. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  84. data/spec/dummy/public/javascripts/effects.js +1123 -0
  85. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  86. data/spec/dummy/public/javascripts/rails.js +202 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/integration/connection_manager_spec.rb +135 -0
  89. data/spec/javascripts/support/jasmine.yml +52 -0
  90. data/spec/javascripts/support/jasmine_helper.rb +38 -0
  91. data/spec/javascripts/support/vendor/sinon-1.7.1.js +4343 -0
  92. data/spec/javascripts/websocket_rails/channel_spec.coffee +112 -0
  93. data/spec/javascripts/websocket_rails/event_spec.coffee +81 -0
  94. data/spec/javascripts/websocket_rails/helpers.coffee +6 -0
  95. data/spec/javascripts/websocket_rails/websocket_connection_spec.coffee +158 -0
  96. data/spec/javascripts/websocket_rails/websocket_rails_spec.coffee +273 -0
  97. data/spec/spec_helper.rb +41 -0
  98. data/spec/spec_helpers/matchers/route_matchers_spec.rb +109 -0
  99. data/spec/spec_helpers/matchers/trigger_matchers_spec.rb +358 -0
  100. data/spec/spec_helpers/spec_helper_event_spec.rb +66 -0
  101. data/spec/support/helper_methods.rb +42 -0
  102. data/spec/support/mock_web_socket.rb +41 -0
  103. data/spec/unit/base_controller_spec.rb +74 -0
  104. data/spec/unit/channel_manager_spec.rb +58 -0
  105. data/spec/unit/channel_spec.rb +169 -0
  106. data/spec/unit/connection_adapters/http_spec.rb +88 -0
  107. data/spec/unit/connection_adapters/web_socket_spec.rb +30 -0
  108. data/spec/unit/connection_adapters_spec.rb +259 -0
  109. data/spec/unit/connection_manager_spec.rb +148 -0
  110. data/spec/unit/controller_factory_spec.rb +76 -0
  111. data/spec/unit/data_store_spec.rb +106 -0
  112. data/spec/unit/dispatcher_spec.rb +203 -0
  113. data/spec/unit/event_map_spec.rb +120 -0
  114. data/spec/unit/event_queue_spec.rb +36 -0
  115. data/spec/unit/event_spec.rb +181 -0
  116. data/spec/unit/logging_spec.rb +162 -0
  117. data/spec/unit/synchronization_spec.rb +150 -0
  118. data/spec/unit/target_validator_spec.rb +88 -0
  119. data/spec/unit/user_manager_spec.rb +165 -0
  120. metadata +320 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 597346f03088e98723978a05f9a3bda02b4bb2dc
4
+ data.tar.gz: e6d09575099ea548eff0218b781e7ddd21484349
5
+ SHA512:
6
+ metadata.gz: cecbfecaa3337f54302ce33e08ac70f1eacfcdde7582420ff51e0a89283d54a2133de131514d40b6c52e58b66fc38fb29b37199034a10b4703d3d9832aacbd76
7
+ data.tar.gz: 56cb845c697ae92e2328a1deb5220c12472fa90f1a2a55467e224e61355282474c772a6ef07c873bfe7f6107284e5e2eb3b534c61dd1f9a9bad3857334822954
data/CHANGELOG.md ADDED
@@ -0,0 +1,328 @@
1
+ # WebsocketRails Change Log
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
+
35
+ ## Version 0.6.2
36
+
37
+ September 8 2013
38
+
39
+ * Updated Dispatcher#broadcast_message to work with the new
40
+ ConnectionManager connections hash. - Thanks to @Frustrate @moaa
41
+
42
+ ## Version 0.6.1
43
+
44
+ September 6 2013
45
+
46
+ * Fixed the loading of event routes when launched in the production
47
+ environment.
48
+
49
+ ## Version 0.6.0
50
+
51
+ September 3 2013
52
+
53
+ * Added the UserManager accessible through the `WebsocketRails.users`
54
+ method. This allows for triggering events on individual logged in users
55
+ from anywhere inside of your application without the need to create a
56
+ channel for that user.
57
+
58
+ ## Version 0.5.0
59
+
60
+ September 2 2013
61
+
62
+ * Use window.location.protocol to choose between ws:// and wss://
63
+ shcheme. - Thanks to @depili
64
+ * Override ConnectionManager#inspect to clean up the output from `rake
65
+ routes`
66
+ * Added a basic Global UserManager for triggering events on specific users
67
+ from anywhere inside your app without creating a dedicated user channel.
68
+ * Deprecate the old controller observer system and implement full Rails
69
+ AbstractController::Callbacks support. - Thanks to @pitr
70
+ * Reload the events.rb event route file each time an event is fired. -
71
+ Thanks to @moaa
72
+ * Separated the event route file and WebsocketRails configuration files.
73
+ The events.rb now lives in `config/events.rb`. The configuration should
74
+ remain in an initializer located at `config/initializers/websocket_rails.rb`. - Thanks to @moaa
75
+
76
+ ## Version 0.4.9
77
+
78
+ July 9 2013
79
+
80
+ * Updated JavaScript client to properly keep track of the connection state.
81
+ * Added .connection_stale() function to the JavaScript client for easily checking connection state.
82
+
83
+ ## Version 0.4.8
84
+
85
+ July 6 2013
86
+
87
+ * Fix error with class reloading in development with Rails 4
88
+ * Added `connection.close!` method to allow for manually disconnecting users from a WebsocketRails controller.
89
+ * Add a way to unsubscribe from channels via the JavaScript client. - Thanks to @Oxynum
90
+ * Fix handling of `on_error` event in the JavaScript client. - Thanks to @imton
91
+
92
+ ## Version 0.4.7
93
+
94
+ June 6 2013
95
+
96
+ * Fix observer system - Thanks to @pitr
97
+ * Fix spelling mistake in ConnectionAdapters#inspect - Thanks to
98
+ @bmxpert1
99
+ * Prevent duplicate events from being triggered when events are added
100
+ directly to Redis from an outside process. - Thanks to @moaa
101
+ * Only log event data if it is a Hash or String to drastically reduce
102
+ the log file size. - Thanks to @florianguenther
103
+ * Fix the intermittent uninitialized constant
104
+ "WebsocketRails::InternalEvents" error in development. - Thanks to
105
+ @DarkSwoop
106
+
107
+ ## Version 0.4.6
108
+
109
+ May 9 2013
110
+
111
+ * Manually load the Faye::WebSocket Thin adapter to support the latest
112
+ version of the Faye::WebSocket gem. - Thanks to @Traxmaxx
113
+
114
+ ## Version 0.4.5
115
+
116
+ May 5 2013
117
+
118
+ * Fix controller class reloading in development. - Thanks to @florianguenther
119
+
120
+ ## Version 0.4.4
121
+
122
+ April 28 2013
123
+
124
+ * Remove existing subscribers from a channel when making it private to
125
+ eliminate the potential for malicious users to eavesdrop on private
126
+ channels. Addresses issue #72.
127
+ * Prevent the server from crashing when receiving an uploaded file.
128
+ Addresses issue #68.
129
+ * Allow custom routes for the WebSocket server. Users of are
130
+ no longer forced to use the `/websocket` route. - Thanks to @Cominch
131
+
132
+ ## Version 0.4.3
133
+
134
+ March 12 2013
135
+
136
+ * Change the log output in Channel#trigger_event. Fixes issue #61.
137
+ * Cancel the ping timer when removing disconnecting a Connection.
138
+ * Fix uninitialized constant WebsocketRails::Internal controller error.
139
+
140
+ ## Version 0.4.2
141
+
142
+ March 1 2013
143
+
144
+ * Check to make sure ActiveRecord is defined before calling
145
+ ActiveRecord::RecordInvalid in Dispatcher. Fixes issue #54. - Thanks to
146
+ @nessche
147
+
148
+ ## Version 0.4.1
149
+
150
+ February 28 2013
151
+
152
+ * Fix bug in ControllerFactory#reload! that prevented the handling of
153
+ internal events when running in the Development environment. Fixes issue #50. - Thanks to @nessche
154
+
155
+ * Only reload controller classes when Rails config.cache_classes is set
156
+ to false instead of always reloading when in the Rails development
157
+ environment. This better respects the Rails configuration options.
158
+ Addresses issue #51. - Thanks to @ngauthier
159
+
160
+ * Update the Rails engine to handle the new Rails 4 route path. Checks
161
+ the Rails version and adds the correct path for the routes file. Fixes
162
+ issue #49. - Thanks to @sgerrand
163
+
164
+ ## Version 0.4.0
165
+
166
+ February 27 2013
167
+
168
+ __There have been a few breaking changes in the public API since the
169
+ last release. Please review the list below and consult the Wiki for more
170
+ information regarding the usage of the new features.__
171
+
172
+ * Controller instances no longer persist between events that are
173
+ triggered. Each event is processed by a new controller instance,
174
+ similar to a standard Rails request. Since you can no longer use
175
+ instance variables to temporarily persist data between events, there is
176
+ a new Controller Data Store that can be used for this purpose. This
177
+ change addresses issue #31.
178
+
179
+ * The original DataStore class has been deprecated. In it's place are
180
+ the new Controller Data Store and Connection Data Store. As mentioned
181
+ above, the Controller Data Store can be used to persist data between
182
+ events in much the same way that you would use instance variables. The
183
+ Connection Data Store acts like the Rails session store. Use it to store
184
+ data private to a connection. Data in the Connection Data Store can be
185
+ accessed from any controller. Check out the Wiki for more information on
186
+ both.
187
+
188
+ * The `websocket_rails.reload_controllers` event has been deprecated.
189
+ The new Controller instantiation model allows for automatic controller
190
+ class reloading while in the development environment. You no longer
191
+ need to trigger an event to pick up code changes in controllers while
192
+ connections are active.
193
+
194
+ * Real logging support has _finally_ been implemented. Check out the
195
+ configuration WIki for more information on the various logging options
196
+ available.
197
+
198
+ ## Version 0.3.0
199
+
200
+ February 6 2013
201
+
202
+ * Extend the event router DSL to accept routes similar to the routes.rb
203
+ shorthand `controller#action`. - Thanks to @nessche.
204
+
205
+ * Add a custom RSpec matcher suite for verifying event routes
206
+ and easily asserting that WebsocketRails controller actions are
207
+ triggering events correctly. - Also thanks to @nessche.
208
+
209
+ * Fix fiber yielded across threads bug when running in standalone mode
210
+ by disabling Thin threaded mode as default option.
211
+
212
+ ## Version 0.2.1
213
+
214
+ January 29 2013
215
+
216
+ * Fix default redis driver issue that was causing problems when using
217
+ redis while event machine was not running.
218
+
219
+ * Fix undefined data store value issue. Thanks to @burninggramma.
220
+
221
+ ## Version 0.2.0
222
+
223
+ November 25 2012
224
+
225
+ * Add standalone server mode to support non event machine
226
+ based web servers.
227
+
228
+ ## Version 0.1.9
229
+
230
+ November 19 2012
231
+
232
+ * Fix bug that crashed the server when receiving badly formed messages
233
+ through an open websocket. Fixes issue #27.
234
+
235
+ * Add support for communication between multiple server instances and
236
+ background jobs. Solves scaling problems discussed in issue #21.
237
+
238
+ * Fixed client_disconnected event firing twice - Thanks to
239
+ @nickdesaulniers
240
+
241
+ ## Version 0.1.8
242
+
243
+ July 18 2012
244
+
245
+ * Fix bug in Channel#trigger preventing the data from coming through
246
+ properly.
247
+
248
+ ## Version 0.1.7
249
+
250
+ July 17 2012
251
+
252
+ * Fixed botched release of 0.1.6
253
+ * Reorganized directory structure
254
+
255
+ ## Version 0.1.6
256
+
257
+ July 17 2012
258
+
259
+ * Added private channel support - Thanks to @MhdSyrwan
260
+ * Added DSL method for marking channels as private.
261
+ * Added support for attaching success and failure callbacks to triggered
262
+ events on the JavaScript client.
263
+ * Fixed JSON parsing bug in HTTP streaming client when multiple events
264
+ were received together.
265
+ * Added connection keepalive ping/pong timers to ensure clients do not
266
+ disconnect automatically. Ensures HTTP streaming works well on Heroku.
267
+ * Removed the requirement of using the thin-socketrails executable. The
268
+ executable will be removed entirely in the next release.
269
+ * Added Jasmine specs for CoffeeScript client.
270
+ * Exceptions triggered in controller actions are now serialized and
271
+ passed to the failure callback on the client that triggered the
272
+ action.
273
+ * Events triggered on the client before the connection is fully
274
+ established are now queued and sent in bulk once the connection is
275
+ ready.
276
+
277
+ ## Version 0.1.5
278
+
279
+ July 3 2012
280
+
281
+ * Fixed bug in JavaScript client that caused Channels not to dispatch
282
+ correctly.
283
+ * Rewrote JavaScript client in CoffeeScript.
284
+ * Created project Wiki
285
+
286
+ ## Version 0.1.4
287
+
288
+ June 30 2012
289
+
290
+ * Added channel support
291
+ * Fix the JavaScript client to work on the iPad - Thanks to @adamkittelson
292
+ * Add an event queue on the connection object to allow for queueing up
293
+ multiple events before flushing to the client.
294
+ * Add generator for creating the events.rb intializer and requiring the
295
+ client in the application.js sprockets manifest file.
296
+
297
+ ## Version 0.1.3
298
+
299
+ June 22 2012
300
+
301
+ * Added support for namespaced events.
302
+ * Improved event machine scheduling for action processing.
303
+ * Made a client's connection ID private.
304
+ * Bugfixes in the JavaScript event dispatchers.
305
+
306
+ ## Version 0.1.2
307
+
308
+ June 10 2012
309
+
310
+ * Added streaming HTTP support as a fallback from WebSockets.
311
+ * Added example JavaScript event dispatchers.
312
+
313
+ ## Version 0.1.1
314
+
315
+ June 2 2012
316
+
317
+ * Created project home page.
318
+ * Improved test coverage and cleaned up the internals.
319
+
320
+ ## Version 0.1.0
321
+
322
+ April 14 2012
323
+
324
+ * Complete project rewrite.
325
+ * Removed websocket-rack dependency.
326
+ * Enhanced documentation.
327
+ * Added event observers in WebsocketRail Controllers.
328
+ * First stable release!
data/Gemfile ADDED
@@ -0,0 +1,27 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rspec-rails", ">=2.14.0"
6
+ gem "therubyrhino"
7
+ gem "therubyracer"
8
+ gem "jasmine"
9
+ gem "headless"
10
+ gem "selenium-webdriver"
11
+ gem "coffee-script"
12
+ gem "thin"
13
+ gem "eventmachine"
14
+ gem "faye-websocket"
15
+ gem "simplecov"
16
+ gem "ruby_gntp"
17
+ gem "guard"
18
+ gem "guard-rspec"
19
+ gem "guard-coffeescript"
20
+ gem "rb-fsevent"
21
+
22
+ platforms :jruby do
23
+ gem 'activerecord-jdbcsqlite3-adapter', :require => 'jdbc-sqlite3', :require => 'arjdbc'
24
+ end
25
+ platforms :ruby do
26
+ gem 'sqlite3'
27
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Dan Knox and Kyle Whalen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,239 @@
1
+ # Websocket-Rails
2
+
3
+ [![Build Status](https://travis-ci.org/websocket-rails/websocket-rails.png?branch=master)](https://travis-ci.org/websocket-rails/websocket-rails)
4
+ [![Gem Version](https://badge.fury.io/rb/websocket-rails.png)](http://badge.fury.io/rb/websocket-rails)
5
+ [![Code Climate](https://codeclimate.com/github/websocket-rails/websocket-rails.png)](https://codeclimate.com/github/websocket-rails/websocket-rails)
6
+
7
+
8
+ If you haven't done so yet, check out the [Project
9
+ 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.
10
+
11
+ **Find us on IRC #websocket-rails**
12
+
13
+ Stop by #websocket-rails on freenode if you would like to chat or have any
14
+ questions.
15
+
16
+ ## Recent Updates
17
+
18
+ Check out the [CHANGELOG](https://github.com/websocket-rails/websocket-rails/blob/master/CHANGELOG.md) to find out what's new.
19
+
20
+ As of version 0.2.0, non event machine based web servers such as Phusion
21
+ Passenger are supported through the use of the [Standalone Server Mode](https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode).
22
+
23
+ ## Overview
24
+
25
+ Start treating client side events as first class citizens inside your
26
+ Rails application with a built in WebSocket server. Sure, WebSockets
27
+ aren't quite universal yet. That's why we also support streaming HTTP.
28
+ Oh, and if you don't mind running a separate process, you can support
29
+ just about any browser with Flash sockets.
30
+
31
+ ## Installation and Usage Guides
32
+
33
+ * [Installation
34
+ Guide](https://github.com/websocket-rails/websocket-rails/wiki/Installation-and-Setup)
35
+ * [Event
36
+ Router](https://github.com/websocket-rails/websocket-rails/wiki/The-Event-Router)
37
+ * [WebsocketRails Controllers](https://github.com/websocket-rails/websocket-rails/wiki/WebsocketRails Controllers)
38
+ * [Using the JavaScript
39
+ Client](https://github.com/websocket-rails/websocket-rails/wiki/Using-the-JavaScript-Client)
40
+ * [Using
41
+ Channels](https://github.com/websocket-rails/websocket-rails/wiki/Working-with-Channels)
42
+ * [Using Private Channels](https://github.com/websocket-rails/websocket-rails/wiki/Using-Private-Channels)
43
+ * [The
44
+ DataStore](https://github.com/websocket-rails/websocket-rails/wiki/Using-the-DataStore)
45
+ * [Reloading Controllers In Development](https://github.com/websocket-rails/websocket-rails/wiki/Reloading-Controllers-In-Development)
46
+ * [Multiple Servers and Background Jobs](https://github.com/websocket-rails/websocket-rails/wiki/Multiple-Servers-and-Background-Jobs)
47
+ * [Standalone Server Mode](https://github.com/websocket-rails/websocket-rails/wiki/Standalone-Server-Mode)
48
+
49
+ ## Handle Events With Class
50
+
51
+ Map events to controller actions using an Event Router.
52
+
53
+ ````ruby
54
+ WebsocketRails::EventMap.describe do
55
+ namespace :tasks do
56
+
57
+ # using a Hash to specify the target
58
+ subscribe :create, :to => TaskController, :with_method => :create
59
+
60
+ # using the same syntax as routes.rb
61
+ subscribe :update, 'task#update'
62
+
63
+ # if your controller is not a top-level object
64
+ subscribe :create_admin, :to => Admin::TaskController, :with_method => :create
65
+
66
+ subscribe :update_admin, 'admin/task#update'
67
+
68
+ end
69
+ end
70
+ ````
71
+
72
+ Trigger events using our JavaScript client.
73
+
74
+ ````javascript
75
+ var task = {
76
+ name: 'Start taking advantage of WebSockets',
77
+ completed: false
78
+ }
79
+
80
+ var dispatcher = new WebSocketRails('localhost:3000/websocket');
81
+
82
+ dispatcher.trigger('tasks.create', task);
83
+ ````
84
+
85
+ Handle events in your controller.
86
+
87
+ ````ruby
88
+ class TaskController < WebsocketRails::BaseController
89
+ def create
90
+ # The `message` method contains the data received
91
+ task = Task.new message
92
+ if task.save
93
+ send_message :create_success, task, :namespace => :tasks
94
+ else
95
+ send_message :create_fail, task, :namespace => :tasks
96
+ end
97
+ end
98
+ end
99
+ ````
100
+
101
+ Receive the response in the client.
102
+
103
+ ````javascript
104
+ dispatcher.bind('tasks.create_success', function(task) {
105
+ console.log('successfully created ' + task.name);
106
+ });
107
+ ````
108
+
109
+ Or just attach success and failure callbacks to your client events.
110
+
111
+ ````javascript
112
+ var success = function(task) { console.log("Created: " + task.name); }
113
+
114
+ var failure = function(task) {
115
+ console.log("Failed to create Product: " + product.name)
116
+ }
117
+
118
+ dispatcher.trigger('products.create', task, success, failure);
119
+ ````
120
+
121
+ Then trigger them in your controller:
122
+
123
+ ````ruby
124
+ def create
125
+ task = Task.create message
126
+ if task.save
127
+ trigger_success task
128
+ else
129
+ trigger_failure task
130
+ end
131
+ end
132
+ ````
133
+
134
+ Note that if you do not trigger the event, a success will be automatically triggered with no data. You can change this behavior by editing the gem configurations and add : `config.trigger_success_by_default = false`.
135
+
136
+ If you're feeling truly lazy, just trigger the failure callback with an
137
+ exception.
138
+
139
+ ````ruby
140
+ def create
141
+ task = Task.create! message
142
+ trigger_success task # trigger success if the save went alright
143
+ end
144
+ ````
145
+
146
+ That controller is starting to look pretty clean.
147
+
148
+ Now in the failure callback on the client we have access to the record
149
+ and the errors.
150
+
151
+ ````javascript
152
+ var failureCallback = function(task) {
153
+ console.log( task.name );
154
+ console.log( task.errors );
155
+ console.log( "You have " + task.errors.length + " errors." );
156
+ }
157
+ ````
158
+
159
+ You can stop listening to an event now by using the unbind function.
160
+
161
+ ````javascript
162
+ dispatcher.unbind('tasks.create_success');
163
+ ````
164
+
165
+ ## Channel Support
166
+
167
+ Keep your users up to date without waiting for them to refresh the page.
168
+ Subscribe them to a channel and update it from wherever you please.
169
+
170
+ Tune in on the client side.
171
+
172
+ ````javascript
173
+ channel = dispatcher.subscribe('posts');
174
+ channel.bind('new', function(post) {
175
+ console.log('a new post about '+post.title+' arrived!');
176
+ });
177
+ ````
178
+
179
+ Broadcast to the channel from anywhere inside your Rails application. An
180
+ existing controller, a model, a background job, or a new WebsocketRails
181
+ controller.
182
+
183
+ ````ruby
184
+ latest_post = Post.latest
185
+ WebsocketRails[:posts].trigger 'new', latest_post
186
+ ````
187
+
188
+ ## Private Channel Support
189
+
190
+ Need to restrict access to a particular channel? No problem. We've got
191
+ that.
192
+
193
+ Private channels give you the ability to authorize a user's
194
+ subscription using the authorization mechanism of your choice.
195
+
196
+ Just tell WebsocketRails which channels you would like to make private by using the `private_channel` method in the Event Router.
197
+ Then handle the channel authorization by subscribing to the `websocket_rails.subscribe_private` event.
198
+
199
+ ````ruby
200
+ WebsocketRails::EventMap.describe do
201
+ private_channel :secret_posts
202
+
203
+ namespace :websocket_rails
204
+ subscribe :subscribe_private, :to => AuthorizationController, :with_method => :authorize_channels
205
+ end
206
+ ````
207
+
208
+ Or you can always mark any channel as private later on.
209
+
210
+ ````ruby
211
+ WebsocketRails[:secret_posts].make_private
212
+ ````
213
+
214
+ On the client side, you can use the `dispatcher.subscribe_private()`
215
+ method to subscribe to a private channel.
216
+
217
+ 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.
218
+
219
+ ## Credit where credit is due
220
+
221
+ Big thanks to our [contributors](https://github.com/websocket-rails/websocket-rails/graphs/contributors) who have helped keep this project moving.
222
+
223
+ Special thanks to [@nessche](https://github.com/nessche) who provided the improved routing DSL and RSpec matcher suite.
224
+
225
+ The `websocket-rails` organization logo was kindly provided by [Uken Games](http://www.uken.com/).
226
+
227
+ ## Development
228
+
229
+ 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.
230
+
231
+ ## Core Team
232
+
233
+ The current `websocket-rails` core team consists of the following individuals:
234
+
235
+ * [@DanKnox](https://github.com/DanKnox)
236
+ * [@Pitr](https://github.com/pitr)
237
+ * [@moaa](https://github.com/moaa)
238
+
239
+ New contributors and pull requests are always welcome.
data/Rakefile ADDED
@@ -0,0 +1,72 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+ begin
5
+ require 'bundler/setup'
6
+ rescue LoadError
7
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ end
9
+
10
+ begin
11
+ require 'rdoc/task'
12
+ rescue LoadError
13
+ require 'rdoc/rdoc'
14
+ require 'rake/rdoctask'
15
+ RDoc::Task = Rake::RDocTask
16
+ end
17
+
18
+ Bundler::GemHelper.install_tasks
19
+
20
+ RDoc::Task.new(:rdoc) do |rdoc|
21
+ rdoc.rdoc_dir = 'rdoc'
22
+ rdoc.title = 'websocket-rails'
23
+ rdoc.options << '--line-numbers'
24
+ rdoc.rdoc_files.include('README.md')
25
+ rdoc.rdoc_files.include('lib/**/*.rb')
26
+ end
27
+
28
+ require 'rspec/core/rake_task'
29
+
30
+ desc 'Default: run RSpec and Jasmine specs.'
31
+ task :default => :spec_and_jasmine
32
+
33
+ desc "Run specs"
34
+ RSpec::Core::RakeTask.new do |t|
35
+ t.pattern = "./spec/**/*_spec.rb"
36
+ end
37
+
38
+ desc "Run rspec and jasmine:ci at the same time"
39
+ task :spec_and_jasmine do
40
+ Rake::Task["spec"].execute
41
+ Rake::Task["jasmine:ci:headless"].execute
42
+ end
43
+
44
+ desc "Generate code coverage"
45
+ task :coverage do
46
+ ENV['COVERAGE'] = 'true'
47
+ Rake::Task["spec"].execute
48
+ `open coverage/index.html`
49
+ end
50
+
51
+ begin
52
+ require 'jasmine'
53
+ load 'jasmine/tasks/jasmine.rake'
54
+ rescue LoadError
55
+ task :jasmine do
56
+ abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
57
+ end
58
+ end
59
+
60
+ require 'headless'
61
+ require 'selenium-webdriver'
62
+
63
+ namespace :jasmine do
64
+ namespace :ci do
65
+ desc "Run Jasmine CI build headlessly"
66
+ task :headless do
67
+ ENV['DISPLAY'] = ':99.0'
68
+ puts "Running Jasmine Headlessly"
69
+ Rake::Task['jasmine:ci'].invoke
70
+ end
71
+ end
72
+ end