alondra 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.gitignore +9 -0
  2. data/Gemfile +22 -0
  3. data/Gemfile.lock +166 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +177 -0
  6. data/Rakefile +34 -0
  7. data/alondra.gemspec +23 -0
  8. data/app/assets/javascripts/alondra-client.js.coffee.erb +71 -0
  9. data/app/assets/javascripts/moz_websocket.js +5 -0
  10. data/app/assets/javascripts/vendor/jquery.json-2.2.js +178 -0
  11. data/app/assets/javascripts/vendor/json2.js +480 -0
  12. data/app/assets/javascripts/vendor/swfobject.js +4 -0
  13. data/app/assets/javascripts/vendor/web_socket.js +379 -0
  14. data/app/assets/swf/WebSocketMain.swf +0 -0
  15. data/app/helpers/alondra_helper.rb +24 -0
  16. data/lib/alondra/changes_callbacks.rb +52 -0
  17. data/lib/alondra/changes_push.rb +23 -0
  18. data/lib/alondra/channel.rb +84 -0
  19. data/lib/alondra/command.rb +38 -0
  20. data/lib/alondra/command_dispatcher.rb +22 -0
  21. data/lib/alondra/connection.rb +52 -0
  22. data/lib/alondra/event.rb +74 -0
  23. data/lib/alondra/event_listener.rb +86 -0
  24. data/lib/alondra/event_router.rb +27 -0
  25. data/lib/alondra/listener_callback.rb +37 -0
  26. data/lib/alondra/message.rb +35 -0
  27. data/lib/alondra/message_queue.rb +70 -0
  28. data/lib/alondra/message_queue_client.rb +71 -0
  29. data/lib/alondra/push_controller.rb +53 -0
  30. data/lib/alondra/pushing.rb +14 -0
  31. data/lib/alondra/server.rb +44 -0
  32. data/lib/alondra/session_parser.rb +57 -0
  33. data/lib/alondra.rb +80 -0
  34. data/lib/generators/alondra/USAGE +8 -0
  35. data/lib/generators/alondra/alondra_generator.rb +7 -0
  36. data/lib/generators/alondra/templates/alondra +33 -0
  37. data/lib/tasks/alondra_tasks.rake +4 -0
  38. data/script/rails +6 -0
  39. data/test/dummy/Rakefile +7 -0
  40. data/test/dummy/app/assets/javascripts/application.js +9 -0
  41. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  42. data/test/dummy/app/controllers/application_controller.rb +14 -0
  43. data/test/dummy/app/controllers/chats_controller.rb +85 -0
  44. data/test/dummy/app/controllers/messages_controller.rb +12 -0
  45. data/test/dummy/app/controllers/sessions_controller.rb +20 -0
  46. data/test/dummy/app/controllers/users_controller.rb +30 -0
  47. data/test/dummy/app/helpers/application_helper.rb +2 -0
  48. data/test/dummy/app/helpers/chats_helper.rb +6 -0
  49. data/test/dummy/app/helpers/error_messages_helper.rb +23 -0
  50. data/test/dummy/app/helpers/layout_helper.rb +22 -0
  51. data/test/dummy/app/mailers/.gitkeep +0 -0
  52. data/test/dummy/app/models/.gitkeep +0 -0
  53. data/test/dummy/app/models/chat.rb +5 -0
  54. data/test/dummy/app/models/message.rb +4 -0
  55. data/test/dummy/app/models/user.rb +37 -0
  56. data/test/dummy/app/views/chats/_form.html.erb +21 -0
  57. data/test/dummy/app/views/chats/edit.html.erb +6 -0
  58. data/test/dummy/app/views/chats/index.html.erb +23 -0
  59. data/test/dummy/app/views/chats/new.html.erb +5 -0
  60. data/test/dummy/app/views/chats/show.html.erb +49 -0
  61. data/test/dummy/app/views/layouts/application.html.erb +19 -0
  62. data/test/dummy/app/views/sessions/new.html.erb +15 -0
  63. data/test/dummy/app/views/shared/_message.js.erb +1 -0
  64. data/test/dummy/app/views/users/_form.html.erb +20 -0
  65. data/test/dummy/app/views/users/edit.html.erb +3 -0
  66. data/test/dummy/app/views/users/index.html.erb +25 -0
  67. data/test/dummy/app/views/users/new.html.erb +5 -0
  68. data/test/dummy/app/views/users/show.html.erb +15 -0
  69. data/test/dummy/config/application.rb +42 -0
  70. data/test/dummy/config/boot.rb +10 -0
  71. data/test/dummy/config/database.yml +31 -0
  72. data/test/dummy/config/environment.rb +5 -0
  73. data/test/dummy/config/environments/development.rb +27 -0
  74. data/test/dummy/config/environments/production.rb +54 -0
  75. data/test/dummy/config/environments/test.rb +39 -0
  76. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  77. data/test/dummy/config/initializers/inflections.rb +10 -0
  78. data/test/dummy/config/initializers/mime_types.rb +5 -0
  79. data/test/dummy/config/initializers/secret_token.rb +7 -0
  80. data/test/dummy/config/initializers/session_store.rb +9 -0
  81. data/test/dummy/config/initializers/wrap_parameters.rb +12 -0
  82. data/test/dummy/config/locales/en.yml +5 -0
  83. data/test/dummy/config/routes.rb +19 -0
  84. data/test/dummy/config.ru +4 -0
  85. data/test/dummy/db/migrate/20110719090458_create_chats.rb +9 -0
  86. data/test/dummy/db/migrate/20110719090538_create_messages.rb +10 -0
  87. data/test/dummy/db/migrate/20110720193249_create_users.rb +16 -0
  88. data/test/dummy/db/schema.rb +38 -0
  89. data/test/dummy/lib/controller_authentication.rb +48 -0
  90. data/test/dummy/log/.gitkeep +0 -0
  91. data/test/dummy/public/404.html +26 -0
  92. data/test/dummy/public/422.html +26 -0
  93. data/test/dummy/public/500.html +26 -0
  94. data/test/dummy/public/favicon.ico +0 -0
  95. data/test/dummy/public/stylesheets/application.css +75 -0
  96. data/test/dummy/script/rails +6 -0
  97. data/test/integration/push_changes_test.rb +41 -0
  98. data/test/integration/push_messages_test.rb +40 -0
  99. data/test/models/channel_test.rb +49 -0
  100. data/test/models/command_test.rb +29 -0
  101. data/test/models/configuration_test.rb +22 -0
  102. data/test/models/connection_test.rb +18 -0
  103. data/test/models/event_listener_test.rb +217 -0
  104. data/test/models/event_router_test.rb +7 -0
  105. data/test/models/message_queue_client_test.rb +26 -0
  106. data/test/models/message_queue_test.rb +70 -0
  107. data/test/models/pushing_test.rb +34 -0
  108. data/test/performance/message_queue_performance.rb +66 -0
  109. data/test/support/factories.rb +19 -0
  110. data/test/support/integration_helper.rb +18 -0
  111. data/test/support/integration_test.rb +6 -0
  112. data/test/support/mocks/bogus_event.rb +15 -0
  113. data/test/support/mocks/mock_connection.rb +24 -0
  114. data/test/support/mocks/mock_event_router.rb +12 -0
  115. data/test/support/mocks/mock_listener.rb +9 -0
  116. data/test/test_helper.rb +14 -0
  117. metadata +316 -0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ .DS_Store
2
+ .rvmrc
3
+ .bundle/
4
+ log/*.log
5
+ pkg/
6
+ test/dummy/db/*.sqlite3
7
+ test/dummy/log/*.log
8
+ test/dummy/tmp/
9
+
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Pusher server
4
+ gemspec
5
+
6
+ # rails dependecies
7
+ gem "mysql2"
8
+
9
+ # Rails 3.1 - Asset Pipeline
10
+ gem 'json'
11
+ gem 'sass-rails'
12
+ gem 'coffee-script'
13
+ gem 'uglifier'
14
+
15
+ # Rails 3.1 - JavaScript
16
+ gem 'jquery-rails'
17
+
18
+ gem 'capybara'
19
+ gem 'capybara-webkit'
20
+ gem 'launchy'
21
+ gem 'factory_girl'
22
+
data/Gemfile.lock ADDED
@@ -0,0 +1,166 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ alondra (0.0.2)
5
+ daemons
6
+ em-websocket
7
+ em-zeromq (= 0.2.1)
8
+ eventmachine (>= 1.0.0.beta.3)
9
+ ffi-rzmq (= 0.8.0)
10
+ rails (>= 3.1.0)
11
+ uuidtools
12
+
13
+ GEM
14
+ remote: http://rubygems.org/
15
+ specs:
16
+ actionmailer (3.1.1)
17
+ actionpack (= 3.1.1)
18
+ mail (~> 2.3.0)
19
+ actionpack (3.1.1)
20
+ activemodel (= 3.1.1)
21
+ activesupport (= 3.1.1)
22
+ builder (~> 3.0.0)
23
+ erubis (~> 2.7.0)
24
+ i18n (~> 0.6)
25
+ rack (~> 1.3.2)
26
+ rack-cache (~> 1.1)
27
+ rack-mount (~> 0.8.2)
28
+ rack-test (~> 0.6.1)
29
+ sprockets (~> 2.0.2)
30
+ activemodel (3.1.1)
31
+ activesupport (= 3.1.1)
32
+ builder (~> 3.0.0)
33
+ i18n (~> 0.6)
34
+ activerecord (3.1.1)
35
+ activemodel (= 3.1.1)
36
+ activesupport (= 3.1.1)
37
+ arel (~> 2.2.1)
38
+ tzinfo (~> 0.3.29)
39
+ activeresource (3.1.1)
40
+ activemodel (= 3.1.1)
41
+ activesupport (= 3.1.1)
42
+ activesupport (3.1.1)
43
+ multi_json (~> 1.0)
44
+ addressable (2.2.6)
45
+ arel (2.2.1)
46
+ builder (3.0.0)
47
+ capybara (1.1.1)
48
+ mime-types (>= 1.16)
49
+ nokogiri (>= 1.3.3)
50
+ rack (>= 1.0.0)
51
+ rack-test (>= 0.5.4)
52
+ selenium-webdriver (~> 2.0)
53
+ xpath (~> 0.1.4)
54
+ capybara-webkit (0.7.2)
55
+ capybara (>= 1.0.0, < 1.2)
56
+ childprocess (0.2.2)
57
+ ffi (~> 1.0.6)
58
+ coffee-script (2.2.0)
59
+ coffee-script-source
60
+ execjs
61
+ coffee-script-source (1.1.2)
62
+ daemons (1.1.4)
63
+ em-websocket (0.3.5)
64
+ addressable (>= 2.1.1)
65
+ eventmachine (>= 0.12.9)
66
+ em-zeromq (0.2.1)
67
+ eventmachine (>= 1.0.0.beta.3)
68
+ ffi-rzmq (>= 0.7.2)
69
+ erubis (2.7.0)
70
+ eventmachine (1.0.0.beta.4)
71
+ execjs (1.2.9)
72
+ multi_json (~> 1.0)
73
+ factory_girl (2.2.0)
74
+ activesupport
75
+ ffi (1.0.9)
76
+ ffi-rzmq (0.8.0)
77
+ hike (1.2.1)
78
+ i18n (0.6.0)
79
+ jquery-rails (1.0.16)
80
+ railties (~> 3.0)
81
+ thor (~> 0.14)
82
+ json (1.6.1)
83
+ json_pure (1.6.1)
84
+ launchy (2.0.5)
85
+ addressable (~> 2.2.6)
86
+ mail (2.3.0)
87
+ i18n (>= 0.4.0)
88
+ mime-types (~> 1.16)
89
+ treetop (~> 1.4.8)
90
+ mime-types (1.17.2)
91
+ multi_json (1.0.3)
92
+ mysql2 (0.3.7)
93
+ nokogiri (1.5.0)
94
+ polyglot (0.3.3)
95
+ rack (1.3.5)
96
+ rack-cache (1.1)
97
+ rack (>= 0.4)
98
+ rack-mount (0.8.3)
99
+ rack (>= 1.0.0)
100
+ rack-ssl (1.3.2)
101
+ rack
102
+ rack-test (0.6.1)
103
+ rack (>= 1.0)
104
+ rails (3.1.1)
105
+ actionmailer (= 3.1.1)
106
+ actionpack (= 3.1.1)
107
+ activerecord (= 3.1.1)
108
+ activeresource (= 3.1.1)
109
+ activesupport (= 3.1.1)
110
+ bundler (~> 1.0)
111
+ railties (= 3.1.1)
112
+ railties (3.1.1)
113
+ actionpack (= 3.1.1)
114
+ activesupport (= 3.1.1)
115
+ rack-ssl (~> 1.3.2)
116
+ rake (>= 0.8.7)
117
+ rdoc (~> 3.4)
118
+ thor (~> 0.14.6)
119
+ rake (0.9.2.2)
120
+ rdoc (3.11)
121
+ json (~> 1.4)
122
+ rubyzip (0.9.4)
123
+ sass (3.1.10)
124
+ sass-rails (3.1.4)
125
+ actionpack (~> 3.1.0)
126
+ railties (~> 3.1.0)
127
+ sass (>= 3.1.4)
128
+ sprockets (~> 2.0.0)
129
+ tilt (~> 1.3.2)
130
+ selenium-webdriver (2.10.0)
131
+ childprocess (>= 0.2.1)
132
+ ffi (= 1.0.9)
133
+ json_pure
134
+ rubyzip
135
+ sprockets (2.0.3)
136
+ hike (~> 1.2)
137
+ rack (~> 1.0)
138
+ tilt (~> 1.1, != 1.3.0)
139
+ thor (0.14.6)
140
+ tilt (1.3.3)
141
+ treetop (1.4.10)
142
+ polyglot
143
+ polyglot (>= 0.3.1)
144
+ tzinfo (0.3.31)
145
+ uglifier (1.0.4)
146
+ execjs (>= 0.3.0)
147
+ multi_json (>= 1.0.2)
148
+ uuidtools (2.1.2)
149
+ xpath (0.1.4)
150
+ nokogiri (~> 1.3)
151
+
152
+ PLATFORMS
153
+ ruby
154
+
155
+ DEPENDENCIES
156
+ alondra!
157
+ capybara
158
+ capybara-webkit
159
+ coffee-script
160
+ factory_girl
161
+ jquery-rails
162
+ json
163
+ launchy
164
+ mysql2
165
+ sass-rails
166
+ uglifier
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
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,177 @@
1
+ # Alondra
2
+
3
+ Alondra is a push server and framework that adds real time capabilities to
4
+ your rails applications.
5
+
6
+ ## What can I do with Alondra?
7
+
8
+ ### Subscribe clients to channels
9
+
10
+ Alondra allows browsers to subscribe to channels. Any Ruby process that loads
11
+ your Rails environment will be able to push messages to those channels.
12
+
13
+ To subscribe to a channel you can use the built in helper:
14
+
15
+ ```
16
+ <%= alondra_client @chat %>
17
+ ```
18
+
19
+ Alondra uses [conventions to map records and classes to channel names](https://github.com/afcapel/alondra/wiki/Event-conventions).
20
+ The last example will subscribe the browser to a channel named '/chats/:chat_id'.
21
+ Then, the Alondra client will render any message pushed to that channel.
22
+
23
+ If you don't want to use Alondra conventions, you can always provide your own
24
+ channel names:
25
+
26
+ ```
27
+ <%= alondra_client ['my custom channel', 'another channel'] %>
28
+ ```
29
+
30
+ ### Sending push notifications
31
+
32
+ Since Alondra is all Ruby and integrates with your Rails environment, you can
33
+ use your Rails models and views to render push messages. For example, sending
34
+ a push notification from your controller action is as simple as this:
35
+
36
+ ```ruby
37
+ def create
38
+ @chat = Chat.find(params[:chat_id])
39
+ @message = @chat.messages.build(params[:message])
40
+
41
+ if @message.save
42
+ push '/messages/create', :to => @chat
43
+ end
44
+
45
+ respond_with @message
46
+ end
47
+ ```
48
+
49
+ This will render the '/messages/create' view and send the results to all
50
+ clients subscribed to the chat channel.
51
+
52
+ You can send push notifications from any process that loads your Rails
53
+ environment and from any class that includes the Alondra::Pushing module.
54
+ When rendering a push message the local context (that is, the instance
55
+ variables of the caller object) will be available in the view.
56
+
57
+ ### Listening to events
58
+
59
+ Alondra comes bundled with an EventListener class that allows you to react to
60
+ events such as when a client subscribes to a channel.
61
+
62
+ ```ruby
63
+ # A ChatListener will by default listen to events
64
+ # sent to any channel whose name begins with '/chat'
65
+ class ChatListener < Alondra::EventListener
66
+
67
+ # If you want to listen to other channels than the default ones
68
+ # you can specify other patterns with the listen_to method, like
69
+ #
70
+ # listen_to /tion$/
71
+ #
72
+ # That would make your listener receive events from any channel whose
73
+ # name ends in 'ion'
74
+
75
+
76
+ # This will be fired any time a client subscribes to
77
+ # any of the observed channels
78
+ on :subscribed, :to => :member do
79
+
80
+ # If you use Cookie Based Session Store,
81
+ # you can access the Rails session from the listener
82
+ @user = User.find(session[:user_id])
83
+
84
+ # Push notifications from listener
85
+ push '/users/user', :to => channel_name
86
+ end
87
+ end
88
+ ```
89
+
90
+ You can also listen to :unsubscribe, :created, :updated, :destroyed or any
91
+ custom event in the observed channels.
92
+
93
+ ### Push record changes to the client
94
+
95
+ Sometimes you are just interested in pushing record updates to subscribed
96
+ clients. You can do that annotating your model:
97
+
98
+ ```ruby
99
+ class Presence < ActiveRecord::Base
100
+ belongs_to :user
101
+ belongs_to :chat
102
+
103
+ push :changes, :to => :chat
104
+ end
105
+ ```
106
+
107
+ This will push an event (:created, :upated or :destroyed) to the chat channel
108
+ each time a Message instance changes.
109
+
110
+ In the client you can listen to these events using the JavaScript API:
111
+
112
+ ```javascript
113
+
114
+ var alondraClient = new AlondraClient('localhost', 12345, ['/chat_rooms/1']);
115
+
116
+ // render user name when presence is created
117
+
118
+ $(alondraClient).bind("created.Presence", function(event, resource){
119
+ if( $('#user_'+resource.user_id).length == 0 ){
120
+ $('#users').append("<li id='user_" + resource.user_id + "'>" + resource.username + "</li>");
121
+ }
122
+ });
123
+
124
+ // remove user name when presence is destroyed
125
+
126
+ $(alondraClient).bind("destroyed.Presence", function(event, resource){
127
+ $('#user_'+resource.user_id).remove();
128
+ });
129
+
130
+ ```
131
+
132
+ This technique is especially useful if you use something like Backbone.js
133
+ to render your app frontend.
134
+
135
+
136
+ ## Example application
137
+
138
+ You can check the [example application](http://github.com/afcapel/alondra-example)
139
+ to see how some of the features are used.
140
+
141
+ ## Installation
142
+
143
+ Currently Alondra depends on Rails 3.1 and Ruby 1.9. It also uses ZeroMQ for
144
+ interprocess communication, so you need to install the library first. If
145
+ you are using Homebrew on Mac OS X, just type
146
+
147
+ <pre>
148
+ brew install zeromq
149
+ </pre>
150
+
151
+ When ZeroMQ is installed, add the Alondra gem to your Gemfile.
152
+
153
+ <pre>
154
+ gem "alondra"
155
+ </pre>
156
+
157
+ You also will need to install the server initialization script into your app.
158
+ In the shell execute the generator.
159
+
160
+ <pre>
161
+ $ rails g alondra install
162
+ </pre>
163
+
164
+ To run the Alondra server, just call the generated script
165
+
166
+ <pre>
167
+ $ script/alondra start
168
+ </pre>
169
+
170
+ In development mode you can also run the Alondra server in its own thread.
171
+ See the [initializer in the example application](https://github.com/afcapel/alondra-example/blob/master/config/initializers/alondra_server.rb)
172
+ for how to do it.
173
+
174
+ ## Contributors
175
+
176
+ - [Ryan LeCompte](http://github.com/ryanlecompte)
177
+ - [Jaime Iniesta](http://github.com/jaimeiniesta)
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Alondra'
18
+ rdoc.options << '--line-numbers' << '--inline-source'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task :default => :test
data/alondra.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # Provide a simple gemspec so you can easily use your
2
+ # project in your rails apps through git.
3
+ Gem::Specification.new do |s|
4
+ s.name = "alondra"
5
+ s.summary = "Add real time capabilities to your rails app"
6
+ s.description = "Add real time capabilities to your rails app"
7
+ s.version = "0.0.3"
8
+ s.authors = ['Alberto F. Capel', 'Ryan LeCompte']
9
+
10
+ s.files = `git ls-files`.split("\n")
11
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
12
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ s.require_paths = ["lib"]
14
+
15
+ # Dependencies
16
+ s.add_dependency('daemons')
17
+ s.add_dependency('uuidtools')
18
+ s.add_dependency('rails', '>= 3.1.0')
19
+ s.add_dependency('eventmachine', '>= 1.0.0.beta.3')
20
+ s.add_dependency('em-websocket')
21
+ s.add_dependency('ffi-rzmq', '0.8.0')
22
+ s.add_dependency('em-zeromq', '0.2.1')
23
+ end
@@ -0,0 +1,71 @@
1
+ #= require "moz_websocket"
2
+ #= require "vendor/jquery.json-2.2"
3
+ #= require "vendor/swfobject"
4
+ #= require "vendor/web_socket"
5
+ //= provide "../swf"
6
+
7
+ window.WEB_SOCKET_SWF_LOCATION = "<%= asset_path 'WebSocketMain.swf' %>"
8
+
9
+ class @AlondraClient
10
+ constructor: (host, port, channels, token = null, retry = 5000) ->
11
+ @channels = channels
12
+ @token = token
13
+ @retry = retry
14
+ @url = "ws://#{host}:#{port}"
15
+
16
+ @url += "?token=#{@token}" if @token
17
+
18
+ this.connect()
19
+
20
+ subscribe: (channel) ->
21
+ subscription =
22
+ command: 'subscribe'
23
+ channel: channel
24
+
25
+ @socket.send $.toJSON(subscription)
26
+
27
+ connect: ->
28
+ @socket = new WebSocket(@url)
29
+
30
+ @socket.onopen = () =>
31
+ if @reconnectInterval
32
+ clearInterval(@reconnectInterval)
33
+ @reconnectInterval = null
34
+
35
+ if @channels instanceof Array
36
+ this.subscribe(channel) for channel in @channels
37
+ else
38
+ this.subscribe(@channels)
39
+
40
+ @socket.onclose = () =>
41
+ this.reconnect()
42
+
43
+
44
+ @socket.onmessage = (message) =>
45
+ msg = $.parseJSON(message.data)
46
+ if msg.event
47
+ this.process(msg)
48
+ else
49
+ this.execute(msg)
50
+
51
+
52
+ @socket.onerror = (error) =>
53
+ this.reconnect()
54
+
55
+ process: (serverEvent) ->
56
+ eventName = serverEvent.event
57
+ resourceType = serverEvent.resource_type
58
+ resource = serverEvent.resource
59
+
60
+ $(this).trigger("#{eventName}.#{resourceType}", resource)
61
+
62
+ execute: (message) ->
63
+ eval(message.message)
64
+
65
+ reconnect: ->
66
+ return if !@retry || @reconnectInterval
67
+
68
+ @reconnectInterval = setInterval =>
69
+ this.connect()
70
+ ,@retry
71
+
@@ -0,0 +1,5 @@
1
+ /* In Firefox 6 WebSocket has been renamed to MozWebSocket */
2
+
3
+ if( window.WebSocket == null && window.MozWebSocket ){
4
+ window.WebSocket = window.MozWebSocket;
5
+ }