pubnub 3.6.10 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pubnub might be problematic. Click here for more details.

Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.txt +3 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +144 -10
  5. data/examples/demo_console.rb +61 -23
  6. data/fixtures/vcr_cassettes/cg/add-c-as-array.yml +51 -0
  7. data/fixtures/vcr_cassettes/cg/add-c-as-csv.yml +51 -0
  8. data/fixtures/vcr_cassettes/cg/add-c-as-string.yml +51 -0
  9. data/fixtures/vcr_cassettes/cg/add-c-as-symbol.yml +51 -0
  10. data/fixtures/vcr_cassettes/cg/audit-cg.yml +44 -0
  11. data/fixtures/vcr_cassettes/cg/audit-ns.yml +44 -0
  12. data/fixtures/vcr_cassettes/cg/grant-cg.yml +44 -0
  13. data/fixtures/vcr_cassettes/cg/grant-ns.yml +44 -0
  14. data/fixtures/vcr_cassettes/cg/here_now-cg.yml +51 -0
  15. data/fixtures/vcr_cassettes/cg/leave-cg-c.yml +132 -0
  16. data/fixtures/vcr_cassettes/cg/leave-cg.yml +133 -0
  17. data/fixtures/vcr_cassettes/cg/list-all-c-in-in-ns-cg.yml +50 -0
  18. data/fixtures/vcr_cassettes/cg/list-all-c-in-non-ns-cg.yml +51 -0
  19. data/fixtures/vcr_cassettes/cg/list-all-cg-in-ns.yml +51 -0
  20. data/fixtures/vcr_cassettes/cg/list-all-namespaces.yml +50 -0
  21. data/fixtures/vcr_cassettes/cg/list-all-non-namespaced-cg.yml +49 -0
  22. data/fixtures/vcr_cassettes/cg/remove-c-as-array.yml +51 -0
  23. data/fixtures/vcr_cassettes/cg/remove-c-as-csv.yml +51 -0
  24. data/fixtures/vcr_cassettes/cg/remove-c-as-string.yml +51 -0
  25. data/fixtures/vcr_cassettes/cg/remove-c-as-symbol.yml +51 -0
  26. data/fixtures/vcr_cassettes/cg/remove-cg-from-ns-csv.yml +51 -0
  27. data/fixtures/vcr_cassettes/cg/remove-ns-csv.yml +51 -0
  28. data/fixtures/vcr_cassettes/cg/subscribe-cg-and-channel.yml +85 -0
  29. data/fixtures/vcr_cassettes/cg/subscribe-cg-only.yml +85 -0
  30. data/lib/pubnub/client.rb +6 -2
  31. data/lib/pubnub/envelope.rb +1 -0
  32. data/lib/pubnub/event.rb +105 -20
  33. data/lib/pubnub/events/audit.rb +13 -0
  34. data/lib/pubnub/events/channel_registration.rb +132 -0
  35. data/lib/pubnub/events/grant.rb +17 -7
  36. data/lib/pubnub/events/heartbeat.rb +29 -3
  37. data/lib/pubnub/events/here_now.rb +21 -7
  38. data/lib/pubnub/events/leave.rb +27 -3
  39. data/lib/pubnub/events/presence.rb +4 -3
  40. data/lib/pubnub/events/set_state.rb +16 -3
  41. data/lib/pubnub/events/state.rb +15 -9
  42. data/lib/pubnub/events/subscribe.rb +17 -3
  43. data/lib/pubnub/formatter.rb +31 -7
  44. data/lib/pubnub/pam.rb +4 -3
  45. data/lib/pubnub/version.rb +1 -1
  46. data/spec/lib/integration/channel_groups_spec.rb +120 -0
  47. data/spec/lib/integration/channel_registration_spec.rb +317 -0
  48. data/spec/spec_helper.rb +0 -1
  49. metadata +31 -2
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/v1/channel-registration/sub-key/demo/namespace/foo/channel-group/foo?pnsdk=PubNub-Ruby/3.7.0beta0&remove=one&uuid=7508c869-9965-432e-9c0c-931cb960b628
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Connection:
17
+ - keep-alive
18
+ Keep-Alive:
19
+ - 30
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Tue, 04 Nov 2014 14:19:30 GMT
27
+ Content-Type:
28
+ - text/javascript; charset="UTF-8"
29
+ Content-Length:
30
+ - '79'
31
+ Connection:
32
+ - keep-alive
33
+ Cache-Control:
34
+ - no-cache
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ Accept-Ranges:
40
+ - bytes
41
+ Age:
42
+ - '0'
43
+ Server:
44
+ - Pubnub
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"status": 200, "message": "OK", "service": "channel-registry", "error":
48
+ false}'
49
+ http_version:
50
+ recorded_at: Tue, 04 Nov 2014 14:19:30 GMT
51
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/v1/channel-registration/sub-key/demo/namespace/foo/channel-group/foo?pnsdk=PubNub-Ruby/3.7.0beta0&remove=one&uuid=9f5732f0-1b41-4247-bbaf-11346ecc1a20
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Connection:
17
+ - keep-alive
18
+ Keep-Alive:
19
+ - 30
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Tue, 04 Nov 2014 14:19:29 GMT
27
+ Content-Type:
28
+ - text/javascript; charset="UTF-8"
29
+ Content-Length:
30
+ - '79'
31
+ Connection:
32
+ - keep-alive
33
+ Cache-Control:
34
+ - no-cache
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ Accept-Ranges:
40
+ - bytes
41
+ Age:
42
+ - '0'
43
+ Server:
44
+ - Pubnub
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"status": 200, "message": "OK", "service": "channel-registry", "error":
48
+ false}'
49
+ http_version:
50
+ recorded_at: Tue, 04 Nov 2014 14:19:29 GMT
51
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/v1/channel-registration/sub-key/demo/namespace/foo/channel-group/foo/remove?pnsdk=PubNub-Ruby/3.7.0beta0&uuid=908068fb-7415-44df-8dab-805db02eebad
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Connection:
17
+ - keep-alive
18
+ Keep-Alive:
19
+ - 30
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Tue, 04 Nov 2014 15:46:27 GMT
27
+ Content-Type:
28
+ - text/javascript; charset="UTF-8"
29
+ Content-Length:
30
+ - '79'
31
+ Connection:
32
+ - keep-alive
33
+ Cache-Control:
34
+ - no-cache
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ Accept-Ranges:
40
+ - bytes
41
+ Age:
42
+ - '0'
43
+ Server:
44
+ - Pubnub
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"status": 200, "message": "OK", "service": "channel-registry", "error":
48
+ false}'
49
+ http_version:
50
+ recorded_at: Tue, 04 Nov 2014 15:46:27 GMT
51
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,51 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/v1/channel-registration/sub-key/demo/namespace/foo/remove?pnsdk=PubNub-Ruby/3.7.0beta0&uuid=7ce7b2c1-060d-48ae-a669-b13bd7087579
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Connection:
17
+ - keep-alive
18
+ Keep-Alive:
19
+ - 30
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Tue, 04 Nov 2014 15:46:33 GMT
27
+ Content-Type:
28
+ - text/javascript; charset="UTF-8"
29
+ Content-Length:
30
+ - '79'
31
+ Connection:
32
+ - keep-alive
33
+ Cache-Control:
34
+ - no-cache
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ Accept-Ranges:
40
+ - bytes
41
+ Age:
42
+ - '0'
43
+ Server:
44
+ - Pubnub
45
+ body:
46
+ encoding: UTF-8
47
+ string: '{"status": 200, "message": "OK", "service": "channel-registry", "error":
48
+ false}'
49
+ http_version:
50
+ recorded_at: Tue, 04 Nov 2014 15:46:33 GMT
51
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,85 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/subscribe/demo/bot/0/0?channel-group=foo:foo&pnsdk=PubNub-Ruby/3.7.0beta0&uuid=0a42a66b-0dca-4566-8e36-695125d50c1f
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Connection:
17
+ - keep-alive
18
+ Keep-Alive:
19
+ - 30
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Wed, 05 Nov 2014 11:49:34 GMT
27
+ Content-Type:
28
+ - text/javascript; charset="UTF-8"
29
+ Content-Length:
30
+ - '24'
31
+ Connection:
32
+ - keep-alive
33
+ Cache-Control:
34
+ - no-cache
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ body:
40
+ encoding: UTF-8
41
+ string: '[[],"14151881738727981"]'
42
+ http_version:
43
+ recorded_at: Wed, 05 Nov 2014 11:49:39 GMT
44
+ - request:
45
+ method: get
46
+ uri: http://pubsub.pubnub.com/subscribe/demo/bot/0/14151881738727981?channel-group=foo:foo&pnsdk=PubNub-Ruby/3.7.0beta0&uuid=0a42a66b-0dca-4566-8e36-695125d50c1f
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ''
50
+ headers:
51
+ Accept-Encoding:
52
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
53
+ Accept:
54
+ - "*/*"
55
+ User-Agent:
56
+ - Ruby
57
+ Connection:
58
+ - keep-alive
59
+ Keep-Alive:
60
+ - 30
61
+ response:
62
+ status:
63
+ code: 200
64
+ message: OK
65
+ headers:
66
+ Date:
67
+ - Wed, 05 Nov 2014 11:49:35 GMT
68
+ Content-Type:
69
+ - text/javascript; charset="UTF-8"
70
+ Content-Length:
71
+ - '80'
72
+ Connection:
73
+ - keep-alive
74
+ Cache-Control:
75
+ - no-cache
76
+ Access-Control-Allow-Origin:
77
+ - "*"
78
+ Access-Control-Allow-Methods:
79
+ - GET
80
+ body:
81
+ encoding: UTF-8
82
+ string: '[["*****.......... 3520 - 2014-11-05 03:49:35"],"14151881750508799","bot","bot"]'
83
+ http_version:
84
+ recorded_at: Wed, 05 Nov 2014 11:49:40 GMT
85
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,85 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://pubsub.pubnub.com/subscribe/demo/,/0/0?channel-group=foo:foo&pnsdk=PubNub-Ruby/3.7.0beta0&uuid=0a3f303a-6242-434a-a491-f85ee00fab26
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ Connection:
17
+ - keep-alive
18
+ Keep-Alive:
19
+ - 30
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Date:
26
+ - Wed, 05 Nov 2014 12:08:46 GMT
27
+ Content-Type:
28
+ - text/javascript; charset="UTF-8"
29
+ Content-Length:
30
+ - '24'
31
+ Connection:
32
+ - keep-alive
33
+ Cache-Control:
34
+ - no-cache
35
+ Access-Control-Allow-Origin:
36
+ - "*"
37
+ Access-Control-Allow-Methods:
38
+ - GET
39
+ body:
40
+ encoding: UTF-8
41
+ string: '[[],"14151893249234255"]'
42
+ http_version:
43
+ recorded_at: Wed, 05 Nov 2014 12:08:51 GMT
44
+ - request:
45
+ method: get
46
+ uri: http://pubsub.pubnub.com/subscribe/demo/,/0/14151893249234255?channel-group=foo:foo&pnsdk=PubNub-Ruby/3.7.0beta0&uuid=0a3f303a-6242-434a-a491-f85ee00fab26
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ''
50
+ headers:
51
+ Accept-Encoding:
52
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
53
+ Accept:
54
+ - "*/*"
55
+ User-Agent:
56
+ - Ruby
57
+ Connection:
58
+ - keep-alive
59
+ Keep-Alive:
60
+ - 30
61
+ response:
62
+ status:
63
+ code: 200
64
+ message: OK
65
+ headers:
66
+ Date:
67
+ - Wed, 05 Nov 2014 12:08:46 GMT
68
+ Content-Type:
69
+ - text/javascript; charset="UTF-8"
70
+ Content-Length:
71
+ - '84'
72
+ Connection:
73
+ - keep-alive
74
+ Cache-Control:
75
+ - no-cache
76
+ Access-Control-Allow-Origin:
77
+ - "*"
78
+ Access-Control-Allow-Methods:
79
+ - GET
80
+ body:
81
+ encoding: UTF-8
82
+ string: '[["*****.......... 4495 - 2014-11-05 04:08:46"],"14151893260958179","foo:foo","bot"]'
83
+ http_version:
84
+ recorded_at: Wed, 05 Nov 2014 12:08:51 GMT
85
+ recorded_with: VCR 2.9.2
@@ -16,7 +16,7 @@ module Pubnub
16
16
  attr_reader :env
17
17
  attr_accessor :single_event_connections_pool, :subscribe_event_connections_pool, :uuid, :async_events
18
18
 
19
- EVENTS = %w(publish subscribe presence leave history here_now audit grant revoke time heartbeat where_now state set_state)
19
+ EVENTS = %w(publish subscribe presence leave history here_now audit grant revoke time heartbeat where_now state set_state channel_registration)
20
20
  VERSION = Pubnub::VERSION
21
21
 
22
22
  EVENTS.each do |event_name|
@@ -143,7 +143,7 @@ module Pubnub
143
143
  @env[:respirator] = EM.add_periodic_timer((@env[:heartbeat].to_i/2) - 1) do
144
144
  @env[:subscriptions].each do |origin, subscribe|
145
145
  $logger.debug('Pubnub'){'Pubnub::Client#start_respirator | BUM'}
146
- EM.defer { heartbeat(:channel => subscribe.get_channels){ |e| $logger.debug('Pubnub::Client#start_respirator | bum') } }
146
+ EM.defer { heartbeat(:channel => subscribe.get_channels, :group => subscribe.get_channel_groups ){ |e| $logger.debug('Pubnub::Client#start_respirator | bum') } }
147
147
  end
148
148
  end unless @env[:respirator]
149
149
 
@@ -222,6 +222,10 @@ module Pubnub
222
222
  alias_method :session_uuid=, :set_uuid
223
223
  alias_method :uuid=, :set_uuid
224
224
 
225
+ def uuid
226
+ @env[:uuid]
227
+ end
228
+
225
229
  def set_auth_key(auth_key)
226
230
  leave_all unless @env[:subscriptions].empty?
227
231
  @env[:auth_key] = auth_key
@@ -3,6 +3,7 @@ module Pubnub
3
3
 
4
4
  INSTANCE_VARIABLES = [
5
5
  :channel,
6
+ :channel_group,
6
7
  :error,
7
8
  :error_message,
8
9
  :first,
@@ -7,6 +7,7 @@ module Pubnub
7
7
  @app = app
8
8
  @origin = options[:origin] || app.env[:origin]
9
9
  @channel = options[:channel]
10
+ @channel_group = options[:group]
10
11
  @message = options[:message]
11
12
  @http_sync = options[:http_sync]
12
13
  @callback = options[:callback]
@@ -20,11 +21,16 @@ module Pubnub
20
21
  @publish_key = app.env[:publish_key]
21
22
  @subscribe_key = app.env[:subscribe_key]
22
23
 
24
+ @write = options[:write]
25
+ @read = options[:read]
26
+ @manage = options[:manage]
27
+
23
28
  @response = nil
24
29
  @timetoken = app.env[:timetoken] || 0
25
30
  validate!
26
- @original_channel = format_channels(@channel, false)
27
31
  @channel = format_channels(@channel)
32
+ @channel_group = format_channel_group(options[:group], false)
33
+ @original_channel = format_channels(@channel, false)
28
34
  $logger.debug('Pubnub'){"Event#initialize | Initialized #{self.class.to_s}"}
29
35
  end
30
36
 
@@ -216,8 +222,8 @@ module Pubnub
216
222
  }
217
223
 
218
224
  empty_if_blank = {
219
- :auth => @auth_key,
220
- :uuid => app.env[:uuid]
225
+ :auth => @auth_key,
226
+ :uuid => app.env[:uuid],
221
227
  }
222
228
 
223
229
  empty_if_blank.delete_if {|k, v| v.blank? }
@@ -271,6 +277,10 @@ module Pubnub
271
277
  end
272
278
 
273
279
  module SubscribeEvent
280
+ def initialize(options, app)
281
+ super
282
+ end
283
+
274
284
  def fire(app)
275
285
  begin
276
286
  $logger.debug('Pubnub'){'SubscribeEvent#fire'}
@@ -303,6 +313,15 @@ module Pubnub
303
313
  app.env[:subscriptions][@origin].add_channel(channel, app)
304
314
  end
305
315
 
316
+ @channel_group.each do |cg|
317
+ if app.env[:subscriptions][@origin].get_channel_groups.include?(cg)
318
+ @channel_group.delete(cg)
319
+ $logger.error('Pubnub'){"Already subscribed to channel group #{cg}, you have to leave that channel first"}
320
+ else
321
+ app.env[:subscriptions][@origin].add_channel_group(cg, app)
322
+ end
323
+ end
324
+
306
325
  if @channel.empty?
307
326
  false
308
327
  else
@@ -312,23 +331,43 @@ module Pubnub
312
331
  end
313
332
 
314
333
  if app.env[:subscriptions][@origin].nil?
315
- app.env[:subscriptions][@origin] = self if app.env[:subscriptions][@origin].nil?
316
- app.env[:callbacks_pool][@origin] = Hash.new if app.env[:callbacks_pool][@origin].nil?
317
- app.env[:error_callbacks_pool][@origin] = @error_callback if app.env[:error_callbacks_pool][@origin].nil?
334
+ app.env[:subscriptions][@origin] = self if app.env[:subscriptions][@origin].nil?
335
+ app.env[:callbacks_pool] = Hash.new if app.env[:callbacks_pool].nil?
336
+ app.env[:callbacks_pool][:channel] = Hash.new if app.env[:callbacks_pool][:channel].nil?
337
+ app.env[:callbacks_pool][:channel_group] = Hash.new if app.env[:callbacks_pool][:channel_group].nil?
338
+ app.env[:callbacks_pool][:channel][@origin] = Hash.new if app.env[:callbacks_pool][:channel][@origin].nil?
339
+ app.env[:callbacks_pool][:channel_group][@origin] = Hash.new if app.env[:callbacks_pool][:channel_group][@origin].nil?
340
+ app.env[:error_callbacks_pool] = Hash.new if app.env[:error_callbacks_pool].nil?
341
+ app.env[:error_callbacks_pool][:channel] = Hash.new if app.env[:error_callbacks_pool][:channel].nil?
342
+ app.env[:error_callbacks_pool][:channel][@origin] = @error_callback if app.env[:error_callbacks_pool][:channel][@origin].nil?
343
+ app.env[:error_callbacks_pool][:channel_group] = Hash.new if app.env[:error_callbacks_pool][:channel_group].nil?
344
+ app.env[:error_callbacks_pool][:channel_group][@origin] = @error_callback if app.env[:error_callbacks_pool][:channel_group][@origin].nil?
318
345
 
319
346
  @channel.each do |channel|
320
- app.env[:callbacks_pool][@origin][channel] = Hash.new
347
+ app.env[:callbacks_pool][:channel][@origin][channel] = Hash.new
348
+ app.env[:callbacks_pool][:channel][@origin][channel][:callback] = @callback unless app.env[:callbacks_pool][:channel][@origin][:callback]
349
+ end
321
350
 
322
- app.env[:callbacks_pool][@origin][channel][:callback] = @callback unless app.env[:callbacks_pool][@origin][:callback]
351
+ @channel_group.each do |channel_group|
352
+ app.env[:callbacks_pool][:channel_group][@origin][channel_group] = Hash.new
353
+ app.env[:callbacks_pool][:channel_group][@origin][channel_group][:callback] = @callback unless app.env[:callbacks_pool][:channel_group][@origin][:callback]
323
354
  end
324
355
 
325
356
  else
326
357
  @channel.each do |channel|
327
- app.env[:callbacks_pool][@origin][channel] = Hash.new
328
- app.env[:callbacks_pool][@origin][channel] = Hash.new
358
+ app.env[:callbacks_pool][:channel][@origin][channel] = Hash.new
359
+ app.env[:callbacks_pool][:channel][@origin][channel] = Hash.new
360
+
361
+ app.env[:callbacks_pool][:channel][@origin][channel][:callback] = @callback unless app.env[:callbacks_pool][:channel][@origin][:callback]
362
+ app.env[:callbacks_pool][:channel][@origin][channel][:error_callback] = @error_callback unless app.env[:callbacks_pool][:channel][@origin][:error_callback]
363
+ end
364
+
365
+ @channel_group.each do |channel_group|
366
+ app.env[:callbacks_pool][:channel_group][@origin][channel_group] = Hash.new
367
+ app.env[:callbacks_pool][:channel_group][@origin][channel_group] = Hash.new
329
368
 
330
- app.env[:callbacks_pool][@origin][channel][:callback] = @callback unless app.env[:callbacks_pool][@origin][:callback]
331
- app.env[:callbacks_pool][@origin][channel][:error_callback] = @error_callback unless app.env[:callbacks_pool][@origin][:error_callback]
369
+ app.env[:callbacks_pool][:channel_group][@origin][channel_group][:callback] = @callback unless app.env[:callbacks_pool][:channel_group][@origin][:callback]
370
+ app.env[:callbacks_pool][:channel_group][@origin][channel_group][:error_callback] = @error_callback unless app.env[:callbacks_pool][:channel_group][@origin][:error_callback]
332
371
  end
333
372
  end
334
373
 
@@ -344,6 +383,11 @@ module Pubnub
344
383
  @timetoken = timetoken
345
384
  end
346
385
 
386
+ def add_channel_group(cg, app)
387
+ @channel_group << cg
388
+ $logger.debug('Pubnub'){'SubscribeEvent#add_channel | Added channel'}
389
+ end
390
+
347
391
  def add_channel(channel, app)
348
392
  @channel = @channel + format_channels(channel)
349
393
  $logger.debug('Pubnub'){'SubscribeEvent#add_channel | Added channel'}
@@ -353,7 +397,18 @@ module Pubnub
353
397
  @channel = @channel - format_channels(channel)
354
398
  $logger.debug('Pubnub'){'SubscribeEvent#remove_channel | Removed channel'}
355
399
  begin
356
- shutdown_subscribe(app) if @channel.empty?
400
+ shutdown_subscribe(app) if @channel.empty? && @channel_group.empty?
401
+ rescue => e
402
+ $logger.error('Pubnub'){e.message}
403
+ $logger.error('Pubnub'){e.backtrace}
404
+ end
405
+ end
406
+
407
+ def remove_channel_group(channel_group, app)
408
+ @channel_group = @channel_group - format_channel_group(channel_group, false)
409
+ $logger.debug('Pubnub'){'SubscribeEvent#remove_channel | Removed channel'}
410
+ begin
411
+ shutdown_subscribe(app) if @channel.empty? && @channel_group.empty?
357
412
  rescue => e
358
413
  $logger.error('Pubnub'){e.message}
359
414
  $logger.error('Pubnub'){e.backtrace}
@@ -364,11 +419,16 @@ module Pubnub
364
419
  @channel
365
420
  end
366
421
 
422
+ def get_channel_groups
423
+ @channel_group
424
+ end
425
+
367
426
  private
368
427
 
369
428
  def parameters(app)
370
429
  parameters = super(app)
371
430
  parameters.merge!({:heartbeat => app.env[:heartbeat]}) if app.env[:heartbeat]
431
+ parameters.merge!({'channel-group' => format_channel_group(@channel_group, true).join(',')}) unless @channel_group.blank?
372
432
  parameters.merge!({:state => encode_state(app.env[:state][@origin])}) if app.env[:state] && app.env[:state][@origin]
373
433
  parameters
374
434
  end
@@ -404,10 +464,16 @@ module Pubnub
404
464
  begin
405
465
  $logger.debug('Pubnub'){'Event#fire_callbacks async'}
406
466
  envelopes.each do |envelope|
407
- app.env[:callbacks_pool][@origin][envelope.channel][:callback].call(envelope) if !envelope.error && !envelope.timetoken_update
467
+ if envelope.channel_group && app.env[:callbacks_pool][:channel_group][@origin][envelope.channel_group]
468
+ app.env[:callbacks_pool][:channel_group][@origin][envelope.channel_group][:callback].call(envelope) if !envelope.error && !envelope.timetoken_update
469
+ else
470
+ app.env[:callbacks_pool][:channel][@origin][envelope.channel][:callback].call(envelope) if !envelope.error && !envelope.timetoken_update
471
+ end
408
472
  end
409
473
  $logger.debug('Pubnub'){'We can send next request now'}
410
- app.env[:error_callbacks_pool][@origin].call(envelopes.first) if envelopes.first.error
474
+ app.env[:error_callbacks_pool][:channel][@origin].call(envelopes.first) if envelopes.first.error && !envelopes.first.channel_group
475
+ app.env[:error_callbacks_pool][:channel_group][@origin].call(envelopes.first) if envelopes.first.error && envelopes.first.channel_group
476
+
411
477
  rescue => error
412
478
  $logger.error('Pubnub'){error}
413
479
  $logger.error('Pubnub'){error.backtrace}
@@ -428,10 +494,6 @@ module Pubnub
428
494
  app.subscribe_event_connections_pool[@origin]
429
495
  end
430
496
 
431
- def channels_for_url(channels)
432
- channels.join(',')
433
- end
434
-
435
497
  def path(app)
436
498
  path = "/subscribe/#{@subscribe_key}/#{channels_for_url(@channel)}/0/#{@timetoken}".gsub(/\?/,'%3F')
437
499
  end
@@ -478,7 +540,7 @@ module Pubnub
478
540
  },
479
541
  app
480
542
  )
481
- else
543
+ elsif parsed_response.length < 4
482
544
  $logger.debug('Pubnub'){'Subscribe#format_envelopes | Not timetoken update'}
483
545
 
484
546
  if parsed_response[2]
@@ -509,6 +571,29 @@ module Pubnub
509
571
 
510
572
  $logger.debug('Pubnub'){'Subscribe#format_envelopes | Envelopes created'}
511
573
 
574
+ end
575
+ else
576
+ $logger.debug('Pubnub'){'Subscribe#format_envelopes | Not timetoken update'}
577
+
578
+ parsed_response[0].size.times do |i|
579
+ channel = parsed_response[3].split(',')[i]
580
+ channel_group = parsed_response[2].split(',')[i]
581
+
582
+ $logger.debug('Pubnub'){"#{parsed_response}"}
583
+
584
+ envelopes << Envelope.new(
585
+ {
586
+ :message => message(parsed_response, i, channel, app),
587
+ :channel => channel,
588
+ :channel_group => channel_group,
589
+ :response_message => parsed_response,
590
+ :timetoken => timetoken(parsed_response)
591
+ },
592
+ app
593
+ )
594
+
595
+ $logger.debug('Pubnub'){'Subscribe#format_envelopes | Envelopes created'}
596
+
512
597
  end
513
598
  end
514
599