pubnub-ruby 3.3.0.7 → 3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.yardoc/checksums +13 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/LICENSE +27 -0
- data/README.md +259 -0
- data/Rakefile +7 -0
- data/VERSION +1 -0
- data/examples/demo_console.rb +198 -0
- data/examples/error_server.rb +28 -0
- data/examples/pubnub_livestream/.gitignore +16 -0
- data/examples/pubnub_livestream/Gemfile +51 -0
- data/examples/pubnub_livestream/Gemfile.lock +191 -0
- data/examples/pubnub_livestream/README.rdoc +28 -0
- data/examples/pubnub_livestream/Rakefile +6 -0
- data/examples/pubnub_livestream/app/assets/images/.keep +0 -0
- data/examples/pubnub_livestream/app/assets/javascripts/application.js +16 -0
- data/examples/pubnub_livestream/app/assets/javascripts/streamer.js.coffee +42 -0
- data/examples/pubnub_livestream/app/assets/stylesheets/application.css.sass +22 -0
- data/examples/pubnub_livestream/app/assets/stylesheets/streamer.css.scss +3 -0
- data/examples/pubnub_livestream/app/controllers/application_controller.rb +5 -0
- data/examples/pubnub_livestream/app/controllers/concerns/.keep +0 -0
- data/examples/pubnub_livestream/app/controllers/streamer_controller.rb +38 -0
- data/examples/pubnub_livestream/app/helpers/application_helper.rb +2 -0
- data/examples/pubnub_livestream/app/helpers/streamer_helper.rb +2 -0
- data/examples/pubnub_livestream/app/mailers/.keep +0 -0
- data/examples/pubnub_livestream/app/models/.keep +0 -0
- data/examples/pubnub_livestream/app/models/concerns/.keep +0 -0
- data/examples/pubnub_livestream/app/models/message.rb +11 -0
- data/examples/pubnub_livestream/app/views/layouts/application.html.erb +14 -0
- data/examples/pubnub_livestream/app/views/streamer/index.haml +22 -0
- data/examples/pubnub_livestream/bin/bundle +3 -0
- data/examples/pubnub_livestream/bin/rails +4 -0
- data/examples/pubnub_livestream/bin/rake +4 -0
- data/examples/pubnub_livestream/config.ru +4 -0
- data/examples/pubnub_livestream/config/application.rb +23 -0
- data/examples/pubnub_livestream/config/boot.rb +4 -0
- data/examples/pubnub_livestream/config/database.yml +25 -0
- data/examples/pubnub_livestream/config/environment.rb +5 -0
- data/examples/pubnub_livestream/config/environments/development.rb +29 -0
- data/examples/pubnub_livestream/config/environments/production.rb +80 -0
- data/examples/pubnub_livestream/config/environments/test.rb +36 -0
- data/examples/pubnub_livestream/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/pubnub_livestream/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/pubnub_livestream/config/initializers/inflections.rb +16 -0
- data/examples/pubnub_livestream/config/initializers/mime_types.rb +5 -0
- data/examples/pubnub_livestream/config/initializers/pubnub.rb +12 -0
- data/examples/pubnub_livestream/config/initializers/secret_token.rb +12 -0
- data/examples/pubnub_livestream/config/initializers/session_store.rb +3 -0
- data/examples/pubnub_livestream/config/initializers/wrap_parameters.rb +14 -0
- data/examples/pubnub_livestream/config/locales/en.yml +23 -0
- data/examples/pubnub_livestream/config/routes.rb +62 -0
- data/examples/pubnub_livestream/db/migrate/20130826110322_create_messages.rb +11 -0
- data/examples/pubnub_livestream/db/schema.rb +24 -0
- data/examples/pubnub_livestream/db/seeds.rb +7 -0
- data/examples/pubnub_livestream/lib/assets/.keep +0 -0
- data/examples/pubnub_livestream/lib/tasks/.keep +0 -0
- data/examples/pubnub_livestream/log/.keep +0 -0
- data/examples/pubnub_livestream/public/404.html +58 -0
- data/examples/pubnub_livestream/public/422.html +58 -0
- data/examples/pubnub_livestream/public/500.html +57 -0
- data/examples/pubnub_livestream/public/assets/application-22a604196dfb65fd0d602eb1eb65f9b7.js +4 -0
- data/examples/pubnub_livestream/public/assets/application-22a604196dfb65fd0d602eb1eb65f9b7.js.gz +0 -0
- data/examples/pubnub_livestream/public/assets/application-3fac0c014bbdf9ee7b3986ff615d5da0.css +5019 -0
- data/examples/pubnub_livestream/public/assets/application-3fac0c014bbdf9ee7b3986ff615d5da0.css.gz +0 -0
- data/examples/pubnub_livestream/public/assets/application-f06834e402639ad43230e3859b9bdd78.css +1 -0
- data/examples/pubnub_livestream/public/assets/application-f06834e402639ad43230e3859b9bdd78.css.gz +0 -0
- data/examples/pubnub_livestream/public/assets/application-f91b87f490140d86003c46b4d06b6c70.js +10682 -0
- data/examples/pubnub_livestream/public/assets/application-f91b87f490140d86003c46b4d06b6c70.js.gz +0 -0
- data/examples/pubnub_livestream/public/assets/manifest-c129e1f5ec52d8b661ebfa902554a2e2.json +1 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-0bc0341283e3bb8ec518375794cc7c28.eot +0 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-24dfb40c91db789b8b8faba6886ac1ef.svg +228 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-4b2130768da98222338d1519f9179528.ttf +0 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-7a07f26f72466361ac9671de2d33fd1c.woff +0 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-9f75212cf9fca594cee7e0e3587db9d1.svg +228 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-ab2f6984951c07fd89e6afdefabd93c7.eot +0 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-c21928f7d46b397b0af6b9ee4a7bd0dd.ttf +0 -0
- data/examples/pubnub_livestream/public/assets/twitter/glyphicons-halflings-regular-fa1d7f79d80d03f8a598822bd9df79bf.woff +0 -0
- data/examples/pubnub_livestream/public/favicon.ico +0 -0
- data/examples/pubnub_livestream/public/robots.txt +5 -0
- data/examples/pubnub_livestream/test/controllers/.keep +0 -0
- data/examples/pubnub_livestream/test/controllers/streamer_controller_test.rb +7 -0
- data/examples/pubnub_livestream/test/fixtures/.keep +0 -0
- data/examples/pubnub_livestream/test/fixtures/messages.yml +9 -0
- data/examples/pubnub_livestream/test/helpers/.keep +0 -0
- data/examples/pubnub_livestream/test/helpers/streamer_helper_test.rb +4 -0
- data/examples/pubnub_livestream/test/integration/.keep +0 -0
- data/examples/pubnub_livestream/test/mailers/.keep +0 -0
- data/examples/pubnub_livestream/test/models/.keep +0 -0
- data/examples/pubnub_livestream/test/models/message_test.rb +7 -0
- data/examples/pubnub_livestream/test/test_helper.rb +15 -0
- data/examples/pubnub_livestream/vendor/assets/javascripts/.keep +0 -0
- data/examples/pubnub_livestream/vendor/assets/stylesheets/.keep +0 -0
- data/examples/serial_publish.rb +46 -0
- data/examples/sinatra/.sass-cache/65d837cc121fc62381bb76d93e5bd081356aa3f9/application.sassc +0 -0
- data/examples/sinatra/.sass-cache/d1525a8542f6e7fb2ecd3275251283768779b344/main.rbc +0 -0
- data/examples/sinatra/.sass-cache/d35765d68c1df11fa3368aa802b3d38109cba214/application.sassc +0 -0
- data/examples/sinatra/main.rb +54 -0
- data/examples/sinatra/public/bootstrap-responsive.min.css +9 -0
- data/examples/sinatra/public/bootstrap.css +5909 -0
- data/examples/sinatra/public/bootstrap.min.css +845 -0
- data/examples/sinatra/public/jquery-1.10.2.min.js +5 -0
- data/examples/sinatra/views/application.sass +6 -0
- data/examples/sinatra/views/index.slim +16 -0
- data/examples/sinatra/views/layout.slim +12 -0
- data/examples/sinatra/views/streamer.coffee +41 -0
- data/examples/sub_and_unsub_1.rb +56 -0
- data/examples/translator.rb +129 -0
- data/lib/pubnub.rb +31 -375
- data/lib/pubnub/client.rb +527 -0
- data/lib/pubnub/configuration.rb +25 -0
- data/lib/pubnub/crypto.rb +53 -0
- data/lib/pubnub/error.rb +23 -0
- data/lib/pubnub/request.rb +288 -0
- data/lib/pubnub/response.rb +126 -0
- data/lib/pubnub/subscription.rb +24 -0
- data/lib/tasks/examples.rake +39 -0
- data/lib/version.rb +1 -0
- data/pubnub.gemspec +26 -0
- data/spec/lib/client_spec.rb +346 -0
- data/spec/lib/crypto_spec.rb +89 -0
- data/spec/lib/history_integration_spec.rb +0 -0
- data/spec/lib/presence_integration_spec.rb +16 -0
- data/spec/lib/publish_integration_spec.rb +994 -0
- data/spec/lib/pubnub_spec.rb +12 -0
- data/spec/lib/request_spec.rb +151 -0
- data/spec/lib/subscribe_integration_spec.rb +944 -0
- data/spec/lib/time_integration_spec.rb +0 -0
- data/spec/spec_helper.rb +15 -0
- metadata +158 -45
- data/lib/pubnub_crypto.rb +0 -53
- data/lib/pubnub_request.rb +0 -310
@@ -0,0 +1,527 @@
|
|
1
|
+
require 'pubnub/configuration.rb'
|
2
|
+
require 'pubnub/subscription.rb'
|
3
|
+
require 'em-http-request'
|
4
|
+
require 'httparty'
|
5
|
+
require 'persistent_httparty'
|
6
|
+
require 'timeout'
|
7
|
+
|
8
|
+
module Pubnub
|
9
|
+
class PubNubHTTParty
|
10
|
+
include HTTParty
|
11
|
+
default_timeout 310
|
12
|
+
|
13
|
+
def first_run?
|
14
|
+
@first_run ? true : false
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_request(path, options={}, &block)
|
18
|
+
if @first_run.nil?
|
19
|
+
@first_run = true
|
20
|
+
else
|
21
|
+
@first_run = false
|
22
|
+
end
|
23
|
+
self.class.get path, options
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Client
|
29
|
+
include Configuration
|
30
|
+
|
31
|
+
attr_accessor :uuid, :cipher_key, :host, :query, :response, :timetoken, :url, :operation, :callback, :publish_key, :subscribe_key, :secret_key, :channel, :jsonp, :message, :ssl, :port
|
32
|
+
attr_accessor :close_connection, :history_limit, :history_count, :history_start, :history_end, :history_reverse, :session_uuid, :last_timetoken, :origin, :error
|
33
|
+
|
34
|
+
|
35
|
+
DEFAULT_CONNECT_CALLBACK = lambda { |msg| $log.info "CONNECTED: #{msg}" }
|
36
|
+
DEFAULT_ERROR_CALLBACK = lambda { |msg| $log.error "AN ERROR OCCURRED: #{msg}" }
|
37
|
+
|
38
|
+
def initialize(options = {})
|
39
|
+
$log = options[:logger]
|
40
|
+
$log = Logger.new('pubnub.log', 0, 100 * 1024 * 1024) unless $log
|
41
|
+
|
42
|
+
@subscriptions = Array.new
|
43
|
+
|
44
|
+
@subscription_request = nil
|
45
|
+
@retry = true
|
46
|
+
@retry_count = 0
|
47
|
+
@callback = options[:callback]
|
48
|
+
@error_callback = options[:error_callback]
|
49
|
+
@error_callback = DEFAULT_ERROR_CALLBACK unless @error_callback
|
50
|
+
@connect_callback = options[:connect_callback]
|
51
|
+
@connect_callback = DEFAULT_CONNECT_CALLBACK unless @connect_callback
|
52
|
+
@cipher_key = options[:cipher_key]
|
53
|
+
@publish_key = options[:publish_key] || DEFAULT_PUBLISH_KEY
|
54
|
+
@subscribe_key = options[:subscribe_key] || DEFAULT_SUBSCRIBE_KEY
|
55
|
+
@channel = options[:channel] || DEFAULT_CHANNEL
|
56
|
+
@message = options[:message]
|
57
|
+
@ssl = options[:ssl]
|
58
|
+
@secret_key = options[:secret_key]
|
59
|
+
@timetoken = options[:timetoken]
|
60
|
+
@session_uuid = options[:uuid] || options[:session_uuid] || UUID.new.generate
|
61
|
+
|
62
|
+
@history_count = options[:count]
|
63
|
+
@history_start = options[:start]
|
64
|
+
@history_end = options[:end]
|
65
|
+
@history_reverse = options[:reverse]
|
66
|
+
|
67
|
+
@port = options[:port]
|
68
|
+
@url = options[:url]
|
69
|
+
@origin = options[:origin]
|
70
|
+
@origin = DEFAULT_ORIGIN unless @origin
|
71
|
+
@query = options[:query]
|
72
|
+
|
73
|
+
@http_sync = options[:http_sync]
|
74
|
+
|
75
|
+
@max_retries = options[:max_retries]
|
76
|
+
@max_retries = MAX_RETRIES unless @max_retries
|
77
|
+
|
78
|
+
@non_subscribe_timeout = options[:non_subscribe_timeout]
|
79
|
+
@non_subscribe_timeout = 5 unless @non_subscribe_timeout
|
80
|
+
|
81
|
+
@reconnect_max_attempts = options[:reconnect_max_attempts]
|
82
|
+
@reconnect_max_attempts = 60 unless @reconnect_max_attempts
|
83
|
+
|
84
|
+
@reconnect_retry_interval = options[:reconnect_retry_interval]
|
85
|
+
@reconnect_retry_interval = 5 unless @reconnect_retry_interval
|
86
|
+
|
87
|
+
@reconnect_response_timeout = options[:reconnect_response_timeout]
|
88
|
+
@reconnect_response_timeout = 5 unless @reconnect_response_timeout
|
89
|
+
|
90
|
+
@sync_connection_sub = Pubnub::PubNubHTTParty.new
|
91
|
+
@sync_connection = Pubnub::PubNubHTTParty.new
|
92
|
+
|
93
|
+
@pause_subscribe = false
|
94
|
+
end
|
95
|
+
|
96
|
+
def publish(options = {}, &block)
|
97
|
+
options[:callback] = block if block_given?
|
98
|
+
options = merge_options(options, 'publish')
|
99
|
+
verify_operation('publish', options)
|
100
|
+
start_request options
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
def subscribe(options = {}, &block)
|
105
|
+
options[:callback] = block if block_given?
|
106
|
+
options = merge_options(options, 'subscribe')
|
107
|
+
verify_operation('subscribe', options)
|
108
|
+
@error_callback.call 'YOU ARE ALREADY SUBSCRIBED TO THAT CHANNEL' if get_channels_for_subscription.include? options[:channel]
|
109
|
+
$log.error 'YOU ARE ALREADY SUBSCRIBED TO THAT CHANNEL' if get_channels_for_subscription.include? options[:channel]
|
110
|
+
start_request options
|
111
|
+
end
|
112
|
+
|
113
|
+
def presence(options = {}, &block)
|
114
|
+
options[:callback] = block if block_given?
|
115
|
+
options = merge_options(options, 'presence')
|
116
|
+
verify_operation('presence', options)
|
117
|
+
start_request options
|
118
|
+
end
|
119
|
+
|
120
|
+
def history(options = {}, &block)
|
121
|
+
options[:callback] = block if block_given?
|
122
|
+
options = merge_options(options, 'history')
|
123
|
+
verify_operation('history', options)
|
124
|
+
options[:params].merge!({:count => options[:count]})
|
125
|
+
options[:params].merge!({:start => options[:start]}) unless options[:start].nil?
|
126
|
+
options[:params].merge!({:end => options[:end]}) unless options[:end].nil?
|
127
|
+
options[:params].merge!({:reverse => 'true'}) if options[:reverse]
|
128
|
+
start_request options
|
129
|
+
end
|
130
|
+
|
131
|
+
def leave(options = {}, &block)
|
132
|
+
options[:callback] = block if block_given?
|
133
|
+
options = merge_options(options, 'leave')
|
134
|
+
verify_operation('leave', options)
|
135
|
+
return false unless get_channels_for_subscription.include? options[:channel]
|
136
|
+
remove_from_subscription options[:channel]
|
137
|
+
if @subscriptions.empty?
|
138
|
+
@timetoken = 0
|
139
|
+
@subscription_request.timetoken = 0
|
140
|
+
@subscribe_connection.close
|
141
|
+
@wait_for_response = false
|
142
|
+
end
|
143
|
+
start_request options
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
alias_method :unsubscribe, :leave
|
148
|
+
|
149
|
+
def here_now(options = {}, &block)
|
150
|
+
options[:callback] = block if block_given?
|
151
|
+
options = merge_options(options, 'here_now')
|
152
|
+
verify_operation('here_now', options)
|
153
|
+
start_request options
|
154
|
+
end
|
155
|
+
|
156
|
+
def time(options = {}, &block)
|
157
|
+
options[:callback] = block if block_given?
|
158
|
+
options = merge_options(options, 'time')
|
159
|
+
verify_operation('time', options)
|
160
|
+
start_request options
|
161
|
+
end
|
162
|
+
|
163
|
+
def subscription_running?
|
164
|
+
@subscription_running
|
165
|
+
end
|
166
|
+
|
167
|
+
def active_subscriptions
|
168
|
+
@subscription_request
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def remove_from_subscription(channel)
|
174
|
+
@subscriptions.delete_if { |s| s.channel.to_s == channel.to_s }
|
175
|
+
end
|
176
|
+
|
177
|
+
def merge_options(options = {}, operation = '')
|
178
|
+
options[:channel] = compile_channel_parameter(options[:channel],options[:channels]) if options[:channel] || options[:channels]
|
179
|
+
return {
|
180
|
+
:ssl => @ssl,
|
181
|
+
:cipher_key => @cipher_key,
|
182
|
+
:publish_key => @publish_key,
|
183
|
+
:subscribe_key => @subscribe_key,
|
184
|
+
:secret_key => @secret_key,
|
185
|
+
:origin => @origin,
|
186
|
+
:operation => operation,
|
187
|
+
:params => { :uuid => @session_uuid },
|
188
|
+
:timetoken => @timetoken,
|
189
|
+
:error_callback=> @error_callback
|
190
|
+
}.merge(options)
|
191
|
+
end
|
192
|
+
|
193
|
+
def start_em_if_not_running
|
194
|
+
Thread.new do
|
195
|
+
EM.run
|
196
|
+
end unless EM.reactor_running?
|
197
|
+
|
198
|
+
until EM.reactor_running? do end
|
199
|
+
end
|
200
|
+
|
201
|
+
def get_channels_for_subscription
|
202
|
+
@subscriptions.map do |sub|
|
203
|
+
sub.channel
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def fire_subscriptions_callback_for(envelope)
|
208
|
+
@subscriptions.each do |subscription|
|
209
|
+
subscription.fire_callback_for envelope
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def start_request(options)
|
214
|
+
request = Pubnub::Request.new(options)
|
215
|
+
unless options[:http_sync]
|
216
|
+
start_em_if_not_running
|
217
|
+
|
218
|
+
if %w(subscribe presence).include? request.operation
|
219
|
+
options[:channel].split(',').each do |channel|
|
220
|
+
@subscriptions << Subscription.new(:channel => channel, :callback => options[:callback], :error_callback => options[:error_callback]) unless get_channels_for_subscription.include? channel
|
221
|
+
end
|
222
|
+
|
223
|
+
@subscription_request = request unless @subscription_request
|
224
|
+
|
225
|
+
if @subscription_request.channel != get_channels_for_subscription.join(',') && @subscription_running
|
226
|
+
@subscribe_connection.close
|
227
|
+
@timetoken = 0
|
228
|
+
@subscription_request.timetoken = 0
|
229
|
+
@wait_for_response = false
|
230
|
+
end
|
231
|
+
|
232
|
+
@subscription_request.channel = get_channels_for_subscription.join(',')
|
233
|
+
|
234
|
+
@subscription_running = EM.add_periodic_timer(PERIODIC_TIMER) do
|
235
|
+
|
236
|
+
unless @wait_for_response || get_channels_for_subscription.empty?
|
237
|
+
@wait_for_response = true
|
238
|
+
$log.debug 'SETTING CHANNELS'
|
239
|
+
@subscription_request.channel = get_channels_for_subscription.join(',')
|
240
|
+
$log.debug 'SENDING SUBSCRIBE REQUEST'
|
241
|
+
http = send_request(@subscription_request)
|
242
|
+
|
243
|
+
http.callback do
|
244
|
+
$log.debug 'GOT SUBSCRIBE RESPONSE'
|
245
|
+
@wait_for_response = false
|
246
|
+
if http.response_header.status.to_i == 200
|
247
|
+
if is_valid_json?(http.response)
|
248
|
+
$log.debug 'GOT VALID JSON'
|
249
|
+
@subscription_request.handle_response(http)
|
250
|
+
$log.debug 'HANDLED RESPONSE'
|
251
|
+
if is_update?(@subscription_request.timetoken)
|
252
|
+
$log.debug 'TIMETOKEN UPDATED'
|
253
|
+
@subscription_request.envelopes.each do |envelope|
|
254
|
+
fire_subscriptions_callback_for envelope
|
255
|
+
end
|
256
|
+
else
|
257
|
+
$log.debug 'TIMETOKEN NOT UPDATED'
|
258
|
+
end
|
259
|
+
end
|
260
|
+
else
|
261
|
+
if request.error_callback
|
262
|
+
request.error_callback.call Pubnub::Response.new(
|
263
|
+
:error_init => true,
|
264
|
+
:message => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json,
|
265
|
+
:response => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json
|
266
|
+
)
|
267
|
+
else
|
268
|
+
fire_subscriptions_callback_for Pubnub::Response.new(
|
269
|
+
:error_init => true,
|
270
|
+
:message => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json,
|
271
|
+
:response => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json
|
272
|
+
)
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
end
|
277
|
+
http.errback do
|
278
|
+
$log.error 'GOT SUBSCRIBE ERROR'
|
279
|
+
@error_callback.call [0, http.error]
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end unless @subscription_running
|
283
|
+
else
|
284
|
+
EM.next_tick do
|
285
|
+
$log.debug 'SENDING OTHER REQUEST'
|
286
|
+
|
287
|
+
http = send_request(request)
|
288
|
+
|
289
|
+
http.errback do
|
290
|
+
@error_callback.call [0, http.error]
|
291
|
+
end
|
292
|
+
|
293
|
+
http.callback do
|
294
|
+
$log.debug 'GOT OTHER RESPONSE'
|
295
|
+
#byebug
|
296
|
+
if http.response_header.status.to_i == 200
|
297
|
+
if is_valid_json?(http.response)
|
298
|
+
request.handle_response(http)
|
299
|
+
request.envelopes.each do |envelope|
|
300
|
+
$log.debug 'CALLING PARAMETER CALLBACK'
|
301
|
+
request.callback.call envelope
|
302
|
+
end
|
303
|
+
end
|
304
|
+
else
|
305
|
+
begin
|
306
|
+
request.handle_response(http)
|
307
|
+
request.envelopes.each do |envelope|
|
308
|
+
if request.error_callback
|
309
|
+
request.error_callback.call envelope
|
310
|
+
else
|
311
|
+
@error_callback.call envelope
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
rescue
|
316
|
+
if request.error_callback
|
317
|
+
request.error_callback.call Pubnub::Response.new(
|
318
|
+
:error_init => true,
|
319
|
+
:message => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json,
|
320
|
+
:response => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json
|
321
|
+
)
|
322
|
+
else
|
323
|
+
@error_callback.call Pubnub::Response.new(
|
324
|
+
:error_init => true,
|
325
|
+
:message => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json,
|
326
|
+
:response => [0, "Bad server response: #{http.response_header.status.to_i}"].to_json
|
327
|
+
)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
else
|
335
|
+
begin
|
336
|
+
if @timetoken.to_i == 0 && request.operation == 'subscribe'
|
337
|
+
time(:http_sync => true){|envelope| @timetoken = envelope.message.to_i }
|
338
|
+
end
|
339
|
+
begin
|
340
|
+
if request.query.to_s.empty?
|
341
|
+
if %w(subscribe presence).include? request.operation
|
342
|
+
response = @sync_connection_sub.send_request(request.origin + request.path, :timeout => 370)
|
343
|
+
else
|
344
|
+
response = @sync_connection.send_request(request.origin + request.path, :timeout => @non_subscribe_timeout)
|
345
|
+
end
|
346
|
+
else
|
347
|
+
if %w(subscribe presence).include? request.operation
|
348
|
+
response = @sync_connection_sub.send_request(request.origin + request.path, :query => request.query, :timeout => 370)
|
349
|
+
else
|
350
|
+
response = @sync_connection.send_request(request.origin + request.path, :query => request.query, :timeout => @non_subscribe_timeout)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
rescue
|
354
|
+
msg = 'ERROR SENDING REQUEST'
|
355
|
+
@error_callback.call Pubnub::Response.new(
|
356
|
+
:error_init => true,
|
357
|
+
:message => [0, msg].to_s,
|
358
|
+
:response => [0, msg].to_s
|
359
|
+
)
|
360
|
+
@retries = 0 unless @retries
|
361
|
+
@retries += 1
|
362
|
+
if @retries <= @max_retries
|
363
|
+
return start_request options
|
364
|
+
else
|
365
|
+
msg = "ERROR SENDING REQUEST AFTER #{@retries} RETRIES"
|
366
|
+
@retries = 0
|
367
|
+
return Pubnub::Response.new(
|
368
|
+
:error_init => true,
|
369
|
+
:message => [0, msg].to_s,
|
370
|
+
:response => [0, msg].to_s
|
371
|
+
)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
if @sync_connection_sub.first_run?
|
376
|
+
@connect_callback.call 'SYNC CONNECTION ESTABLISHED'
|
377
|
+
end
|
378
|
+
if response.response.code.to_i == 200
|
379
|
+
if is_valid_json?(response.body)
|
380
|
+
request.handle_response(response)
|
381
|
+
@timetoken = request.timetoken
|
382
|
+
|
383
|
+
if request.operation == 'leave'
|
384
|
+
Subscription.remove_from_subscription request.channel
|
385
|
+
end
|
386
|
+
|
387
|
+
if !request.callback.nil?
|
388
|
+
request.envelopes.each do |envelope|
|
389
|
+
request.callback.call envelope
|
390
|
+
end
|
391
|
+
else
|
392
|
+
if %w(publish leave here_now time).include? request.operation
|
393
|
+
return request.envelopes[0]
|
394
|
+
else
|
395
|
+
return request.envelopes
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
else
|
400
|
+
begin
|
401
|
+
request.handle_response(response)
|
402
|
+
if !request.callback.nil?
|
403
|
+
request.envelopes.each do |envelope|
|
404
|
+
request.callback.call envelope
|
405
|
+
end
|
406
|
+
else
|
407
|
+
if %w(publish leave here_now time).include? request.operation
|
408
|
+
return request.envelopes[0]
|
409
|
+
else
|
410
|
+
return request.envelopes
|
411
|
+
end
|
412
|
+
end
|
413
|
+
rescue
|
414
|
+
if request.error_callback
|
415
|
+
request.error_callback.call Pubnub::Response.new(
|
416
|
+
:error_init => true,
|
417
|
+
:message => [0, "Bad server response: #{response.response.code.to_i}"].to_json,
|
418
|
+
:response => [0, "Bad server response: #{response.response.code.to_i}"].to_json
|
419
|
+
)
|
420
|
+
else
|
421
|
+
@error_callback.call Pubnub::Response.new(
|
422
|
+
:error_init => true,
|
423
|
+
:message => [0, "Bad server response: #{response.response.code.to_i}"].to_json,
|
424
|
+
:response => [0, "Bad server response: #{response.response.code.to_i}"].to_json
|
425
|
+
)
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
if @sync_retries
|
430
|
+
@sync_retries += 1
|
431
|
+
else
|
432
|
+
@sync_retries = 1
|
433
|
+
end
|
434
|
+
|
435
|
+
if @sync_retries < @max_retries
|
436
|
+
start_request options
|
437
|
+
end
|
438
|
+
end
|
439
|
+
rescue Timeout::Error
|
440
|
+
if request.error_callback
|
441
|
+
request.error_callback.call [0, 'TIMEOUT']
|
442
|
+
else
|
443
|
+
@error_callback.call [0, 'TIMEOUT']
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def send_request(request)
|
450
|
+
if %w(subscribe presence).include? request.operation
|
451
|
+
unless @subscribe_connection
|
452
|
+
@subscribe_connection = EM::HttpRequest.new(request.origin, :connect_timeout => 370, :inactivity_timeout => 370)
|
453
|
+
connection = @subscribe_connection.get :path => '/time/0', :keepalive => true, :query => request.query
|
454
|
+
#EM.next_tick do
|
455
|
+
connection.callback do
|
456
|
+
EM.defer do @connect_callback.call 'ASYNC SUBSCRIBE CONNECTION' end
|
457
|
+
end
|
458
|
+
#end
|
459
|
+
end
|
460
|
+
|
461
|
+
@subscribe_connection.get :path => request.path, :query => request.query, :keepalive => true
|
462
|
+
else
|
463
|
+
unless @connection
|
464
|
+
@connection = EM::HttpRequest.new request.origin
|
465
|
+
end
|
466
|
+
@connection.get :path => request.path, :query => request.query, :keepalive => true
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
def is_update?(timetoken)
|
471
|
+
if @timetoken.to_i < timetoken.to_i
|
472
|
+
@timetoken = timetoken
|
473
|
+
else
|
474
|
+
false
|
475
|
+
end
|
476
|
+
|
477
|
+
end
|
478
|
+
|
479
|
+
def is_valid_json?(response)
|
480
|
+
begin
|
481
|
+
JSON.parse(response)
|
482
|
+
valid = true
|
483
|
+
rescue
|
484
|
+
valid = false
|
485
|
+
end
|
486
|
+
valid
|
487
|
+
end
|
488
|
+
|
489
|
+
def verify_operation(operation, options)
|
490
|
+
case operation
|
491
|
+
when 'publish'
|
492
|
+
raise(ArgumentError, 'publish() requires :channel, :message parameters and, if async, callback parameter or block given.') unless (options[:channel] || options[:channels]) && (options[:callback] || options[:block_given] || options[:http_sync]) && options[:message]
|
493
|
+
when 'subscribe'
|
494
|
+
raise(ArgumentError, 'subscribe() requires :channel parameters and, if async, callback parameter or block given.') unless (options[:channel] || options[:channels]) && (options[:callback] || options[:block_given] || options[:http_sync])
|
495
|
+
when 'presence'
|
496
|
+
raise(ArgumentError, 'presence() requires :channel parameters and, if async, callback parameter or block given.') unless (options[:channel] || options[:channels]) && (options[:callback] || options[:block_given] || options[:http_sync])
|
497
|
+
when 'time'
|
498
|
+
raise(ArgumentError, 'time() require, if async, callback parameter or block given.') unless (options[:callback] || options[:block_given] || options[:http_sync])
|
499
|
+
when 'history'
|
500
|
+
raise(ArgumentError, 'history() requires :channel, :count parameters and, if async, callback parameter or block given.') unless (options[:channel] || options[:channels]) && (options[:callback] || options[:block_given] || options[:http_sync]) && options[:count]
|
501
|
+
when 'here_now'
|
502
|
+
raise(ArgumentError, 'here_now() requires :channel parameters and, if async, callback parameter or block given.') unless (options[:channel] || options[:channels]) && (options[:callback] || options[:block_given] || options[:http_sync])
|
503
|
+
when 'leave'
|
504
|
+
raise(ArgumentError, 'leave() requires :channel parameters and, if async, callback parameter or block given.') unless (options[:channel] || options[:channels]) && (options[:callback] || options[:block_given] || options[:http_sync])
|
505
|
+
end
|
506
|
+
|
507
|
+
unless options[:callback].nil?
|
508
|
+
raise('callback is invalid.') unless options[:callback].respond_to? 'call'
|
509
|
+
end
|
510
|
+
|
511
|
+
unless options[:error_callback].nil?
|
512
|
+
raise('error_callback is invalid.') unless options[:error_callback].respond_to? 'call'
|
513
|
+
end
|
514
|
+
|
515
|
+
end
|
516
|
+
|
517
|
+
def compile_channel_parameter(channel, channels)
|
518
|
+
raise(ArgumentError, 'Can\'t handle both :channel and :channels parameters given.') if channel && channels
|
519
|
+
channel = channels if channels
|
520
|
+
channel = channel.to_s if channel.class == Symbol
|
521
|
+
channel = channel.map! {|c| c.to_s}.join(',') if channel.class == Array
|
522
|
+
return channel
|
523
|
+
end
|
524
|
+
|
525
|
+
end
|
526
|
+
end
|
527
|
+
|