pusher-client 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.travis.yml +1 -2
- data/CHANGELOG.md +19 -0
- data/Gemfile +0 -2
- data/Rakefile +4 -7
- data/lib/pusher-client.rb +0 -2
- data/lib/pusher-client/channel.rb +19 -17
- data/lib/pusher-client/channels.rb +4 -7
- data/lib/pusher-client/socket.rb +81 -60
- data/lib/pusher-client/version.rb +1 -1
- data/lib/pusher-client/websocket.rb +13 -4
- data/pusher-client.gemspec +4 -4
- data/{test/pusherclient_test.rb → spec/pusherclient_spec.rb} +43 -43
- data/{test/teststrap.rb → spec/spec_helper.rb} +4 -3
- metadata +37 -40
- data/test/test.watchr +0 -63
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1cc802ffe2416f85cd407687b0e23f82569c9f15
|
4
|
+
data.tar.gz: 6af614c433c815e762fc308f0de05bd78e6f8e3c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 46fd409658e26cc23b41f77f94d789a61f7b2c9efb19535c3c9cf22c70da8146dacaafb803ae07eb5a0a7a8446b2739157509c3fc170fa7df337ab31111d5913
|
7
|
+
data.tar.gz: a77689a96349a40d574b012f0d2f19df81c79b29d081b835ea0b67bd6ae3bc06758896eea0d91c897a19256e61607b366cd2f9ec5ac661f89467b2259f4a5e14
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
0.5.0 / 2014-04-15
|
3
|
+
==================
|
4
|
+
|
5
|
+
* Updating to protocol v6
|
6
|
+
* Fixes scope issues with user_data
|
7
|
+
* Makes missing user_data on presence channel error explicit
|
8
|
+
* Mask outgoing data.
|
9
|
+
* Update the websocket dependency to 1.1.2
|
10
|
+
* Allow to use app_key that are symbols
|
11
|
+
* Allow to specify the logger when creating a new Socket
|
12
|
+
* Don't set Thread.abort_on_exception = true
|
13
|
+
* Capture Thread exceptions when running async
|
14
|
+
* Not raising an ArgumentError had slipped through the cracks. The test case exist.
|
15
|
+
* Retain a consistent code style with the rest of the code and ruby's unofficial styling.
|
16
|
+
* Add send_channel_event method on socket for client channel events
|
17
|
+
|
18
|
+
0.4.0 and previous not documented :/
|
19
|
+
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,10 +1,7 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
|
3
|
-
require '
|
4
|
-
Rake::TestTask.new(:test) do |test|
|
5
|
-
test.libs << 'lib' << 'test'
|
6
|
-
test.pattern = 'test/**/*_test.rb'
|
7
|
-
test.verbose = true
|
8
|
-
end
|
3
|
+
require 'rspec/core/rake_task'
|
9
4
|
|
10
|
-
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task :default => :spec
|
data/lib/pusher-client.rb
CHANGED
@@ -2,17 +2,19 @@ module PusherClient
|
|
2
2
|
|
3
3
|
class Channel
|
4
4
|
attr_accessor :global, :subscribed
|
5
|
-
attr_reader :name, :callbacks, :
|
5
|
+
attr_reader :name, :callbacks, :user_data
|
6
6
|
|
7
|
-
def initialize(channel_name)
|
7
|
+
def initialize(channel_name, user_data=nil, logger=PusherClient.logger)
|
8
8
|
@name = channel_name
|
9
|
+
@user_data = user_data
|
10
|
+
@logger = logger
|
9
11
|
@global = false
|
10
12
|
@callbacks = {}
|
11
|
-
@global_callbacks = {}
|
12
13
|
@subscribed = false
|
13
14
|
end
|
14
15
|
|
15
16
|
def bind(event_name, &callback)
|
17
|
+
PusherClient.logger.debug "Binding #{event_name} to #{name}"
|
16
18
|
@callbacks[event_name] = callbacks[event_name] || []
|
17
19
|
@callbacks[event_name] << callback
|
18
20
|
return self
|
@@ -20,28 +22,16 @@ module PusherClient
|
|
20
22
|
|
21
23
|
def dispatch_with_all(event_name, data)
|
22
24
|
dispatch(event_name, data)
|
23
|
-
dispatch_global_callbacks(event_name, data)
|
24
25
|
end
|
25
26
|
|
26
27
|
def dispatch(event_name, data)
|
27
|
-
|
28
|
+
logger.debug("Dispatching #{global ? 'global ' : ''}callbacks for #{event_name}")
|
28
29
|
if @callbacks[event_name]
|
29
30
|
@callbacks[event_name].each do |callback|
|
30
31
|
callback.call(data)
|
31
32
|
end
|
32
33
|
else
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def dispatch_global_callbacks(event_name, data)
|
38
|
-
if @global_callbacks[event_name]
|
39
|
-
PusherClient.logger.debug "Dispatching global callbacks for #{event_name}"
|
40
|
-
@global_callbacks[event_name].each do |callback|
|
41
|
-
callback.call(data)
|
42
|
-
end
|
43
|
-
else
|
44
|
-
PusherClient.logger.debug "No global callbacks to dispatch for #{event_name}"
|
34
|
+
logger.debug "No #{global ? 'global ' : ''}callbacks to dispatch for #{event_name}"
|
45
35
|
end
|
46
36
|
end
|
47
37
|
|
@@ -49,6 +39,18 @@ module PusherClient
|
|
49
39
|
@subscribed = true
|
50
40
|
end
|
51
41
|
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :logger
|
45
|
+
end
|
46
|
+
|
47
|
+
class NullChannel
|
48
|
+
def initialize(channel_name, *a)
|
49
|
+
@name = channel_name
|
50
|
+
end
|
51
|
+
def method_missing(*a)
|
52
|
+
raise ArgumentError, "Channel `#{@name}` hasn't been subscribed yet."
|
53
|
+
end
|
52
54
|
end
|
53
55
|
|
54
56
|
end
|
@@ -3,15 +3,13 @@ module PusherClient
|
|
3
3
|
|
4
4
|
attr_reader :channels
|
5
5
|
|
6
|
-
def initialize
|
6
|
+
def initialize(logger=PusherClient.logger)
|
7
|
+
@logger = logger
|
7
8
|
@channels = {}
|
8
9
|
end
|
9
10
|
|
10
|
-
def add(channel_name)
|
11
|
-
|
12
|
-
@channels[channel_name] = Channel.new(channel_name)
|
13
|
-
end
|
14
|
-
@channels[channel_name]
|
11
|
+
def add(channel_name, user_data=nil)
|
12
|
+
@channels[channel_name] ||= Channel.new(channel_name, user_data, @logger)
|
15
13
|
end
|
16
14
|
|
17
15
|
def find(channel_name)
|
@@ -20,7 +18,6 @@ module PusherClient
|
|
20
18
|
|
21
19
|
def remove(channel_name)
|
22
20
|
@channels.delete(channel_name)
|
23
|
-
@channels
|
24
21
|
end
|
25
22
|
|
26
23
|
def empty?
|
data/lib/pusher-client/socket.rb
CHANGED
@@ -6,15 +6,15 @@ module PusherClient
|
|
6
6
|
class Socket
|
7
7
|
|
8
8
|
CLIENT_ID = 'pusher-ruby-client'
|
9
|
-
PROTOCOL = '
|
9
|
+
PROTOCOL = '6'
|
10
10
|
|
11
11
|
attr_reader :path, :connected, :channels, :global_channel, :socket_id
|
12
12
|
|
13
13
|
def initialize(app_key, options={})
|
14
|
-
raise "Missing app_key"
|
14
|
+
raise ArgumentError, "Missing app_key" if app_key.to_s.empty?
|
15
15
|
|
16
16
|
@path = "#{options[:ws_path]}/app/#{app_key}?client=#{CLIENT_ID}&version=#{PusherClient::VERSION}&protocol=#{PROTOCOL}"
|
17
|
-
@key = app_key
|
17
|
+
@key = app_key.to_s
|
18
18
|
@secret = options[:secret]
|
19
19
|
@socket_id = nil
|
20
20
|
@channels = Channels.new
|
@@ -22,12 +22,19 @@ module PusherClient
|
|
22
22
|
@global_channel.global = true
|
23
23
|
@connected = false
|
24
24
|
@encrypted = options[:encrypted] || false
|
25
|
+
@logger = options[:logger] || PusherClient.logger
|
25
26
|
@private_auth_method = options[:private_auth_method]
|
26
27
|
@cert_file = options[:cert_file]
|
27
28
|
@ws_host = options[:ws_host] || HOST
|
28
29
|
@ws_port = options[:ws_port] || WS_PORT
|
29
30
|
@wss_port = options[:wss_port] || WSS_PORT
|
30
|
-
@ssl_verify = options.fetch(:ssl_verify
|
31
|
+
@ssl_verify = options.fetch(:ssl_verify, true)
|
32
|
+
|
33
|
+
if @encrypted
|
34
|
+
@url = "wss://#{@ws_host}:#{@wss_port}#{@path}"
|
35
|
+
else
|
36
|
+
@url = "ws://#{@ws_host}:#{@ws_port}#{@path}"
|
37
|
+
end
|
31
38
|
|
32
39
|
bind('pusher:connection_established') do |data|
|
33
40
|
socket = parser(data)
|
@@ -37,11 +44,12 @@ module PusherClient
|
|
37
44
|
end
|
38
45
|
|
39
46
|
bind('pusher:connection_disconnected') do |data|
|
47
|
+
@connected = false
|
40
48
|
@channels.channels.each { |c| c.disconnect }
|
41
49
|
end
|
42
50
|
|
43
51
|
bind('pusher:error') do |data|
|
44
|
-
|
52
|
+
logger.fatal("Pusher : error : #{data.inspect}")
|
45
53
|
end
|
46
54
|
|
47
55
|
# Keep this in case we're using a websocket protocol that doesn't
|
@@ -52,52 +60,45 @@ module PusherClient
|
|
52
60
|
end
|
53
61
|
|
54
62
|
def connect(async = false)
|
55
|
-
if @
|
56
|
-
|
63
|
+
return if @connection
|
64
|
+
logger.debug("Pusher : connecting : #{@url}")
|
65
|
+
|
66
|
+
if async
|
67
|
+
@connection_thread = Thread.new do
|
68
|
+
begin
|
69
|
+
connect_internal
|
70
|
+
rescue => ex
|
71
|
+
send_local_event "pusher:error", ex
|
72
|
+
end
|
73
|
+
end
|
57
74
|
else
|
58
|
-
|
75
|
+
connect_internal
|
59
76
|
end
|
60
|
-
PusherClient.logger.debug("Pusher : connecting : #{url}")
|
61
|
-
|
62
|
-
@connection_thread = Thread.new {
|
63
|
-
options = {:ssl => @encrypted, :cert_file => @cert_file, :ssl_verify => @ssl_verify}
|
64
|
-
@connection = PusherWebSocket.new(url, options)
|
65
|
-
PusherClient.logger.debug "Websocket connected"
|
66
|
-
|
67
|
-
loop do
|
68
|
-
msg = @connection.receive[0]
|
69
|
-
next if msg.nil?
|
70
|
-
params = parser(msg)
|
71
|
-
next if params['socket_id'] && params['socket_id'] == self.socket_id
|
72
|
-
|
73
|
-
send_local_event params['event'], params['data'], params['channel']
|
74
|
-
end
|
75
|
-
}
|
76
|
-
|
77
|
-
@connection_thread.run
|
78
|
-
@connection_thread.join unless async
|
79
77
|
self
|
80
78
|
end
|
81
79
|
|
82
80
|
def disconnect
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
81
|
+
return unless @connection
|
82
|
+
logger.debug("Pusher : disconnecting")
|
83
|
+
@connected = false
|
84
|
+
@connection.close
|
85
|
+
@connection = nil
|
86
|
+
if @connection_thread
|
87
|
+
@connection_thread.kill
|
88
|
+
@connection_thread = nil
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
92
|
def subscribe(channel_name, user_data = nil)
|
94
93
|
if user_data.is_a? Hash
|
95
|
-
|
96
|
-
elsif
|
97
|
-
|
94
|
+
user_data = user_data.to_json
|
95
|
+
elsif user_data
|
96
|
+
user_data = {:user_id => user_data}.to_json
|
97
|
+
elsif is_presence_channel(channel_name)
|
98
|
+
raise ArgumentError, "user_data is required for presence channels"
|
98
99
|
end
|
99
100
|
|
100
|
-
channel = @channels
|
101
|
+
channel = @channels.add(channel_name, user_data)
|
101
102
|
if @connected
|
102
103
|
authorize(channel, method(:authorize_callback))
|
103
104
|
end
|
@@ -106,7 +107,7 @@ module PusherClient
|
|
106
107
|
|
107
108
|
def unsubscribe(channel_name)
|
108
109
|
channel = @channels.remove channel_name
|
109
|
-
if @connected
|
110
|
+
if channel && @connected
|
110
111
|
send_event('pusher:unsubscribe', {
|
111
112
|
'channel' => channel_name
|
112
113
|
})
|
@@ -120,29 +121,22 @@ module PusherClient
|
|
120
121
|
end
|
121
122
|
|
122
123
|
def [](channel_name)
|
123
|
-
|
124
|
-
@channels[channel_name]
|
125
|
-
else
|
126
|
-
@channels << channel_name
|
127
|
-
end
|
124
|
+
@channels[channel_name] || NullChannel.new(channel_name)
|
128
125
|
end
|
129
126
|
|
130
127
|
def subscribe_all
|
131
|
-
@channels.channels.clone.each{ |k,v|
|
132
|
-
subscribe(k)
|
133
|
-
}
|
128
|
+
@channels.channels.clone.each { |k,v| subscribe(v.name, v.user_data) }
|
134
129
|
end
|
135
130
|
|
136
|
-
#auth for private and presence
|
131
|
+
# auth for private and presence
|
137
132
|
def authorize(channel, callback)
|
138
133
|
if is_private_channel(channel.name)
|
139
134
|
auth_data = get_private_auth(channel)
|
140
135
|
elsif is_presence_channel(channel.name)
|
141
136
|
auth_data = get_presence_auth(channel)
|
142
|
-
channel_data = @user_data
|
143
137
|
end
|
144
138
|
# could both be nil if didn't require auth
|
145
|
-
callback.call(channel, auth_data,
|
139
|
+
callback.call(channel, auth_data, channel.user_data)
|
146
140
|
end
|
147
141
|
|
148
142
|
def authorize_callback(channel, auth_data, channel_data)
|
@@ -163,7 +157,7 @@ module PusherClient
|
|
163
157
|
end
|
164
158
|
|
165
159
|
def get_private_auth(channel)
|
166
|
-
if
|
160
|
+
if @private_auth_method.nil?
|
167
161
|
string_to_sign = @socket_id + ':' + channel.name
|
168
162
|
signature = hmac(@secret, string_to_sign)
|
169
163
|
return "#{@key}:#{signature}"
|
@@ -173,41 +167,68 @@ module PusherClient
|
|
173
167
|
end
|
174
168
|
|
175
169
|
def get_presence_auth(channel)
|
176
|
-
string_to_sign = @socket_id + ':' + channel.name + ':' +
|
170
|
+
string_to_sign = @socket_id + ':' + channel.name + ':' + channel.user_data
|
177
171
|
signature = hmac(@secret, string_to_sign)
|
178
172
|
return "#{@key}:#{signature}"
|
179
173
|
end
|
180
174
|
|
181
175
|
|
182
|
-
#
|
176
|
+
# for compatibility with JavaScript client API
|
183
177
|
alias :subscribeAll :subscribe_all
|
184
178
|
|
185
179
|
def send_event(event_name, data)
|
186
180
|
payload = {'event' => event_name, 'data' => data}.to_json
|
187
181
|
@connection.send(payload)
|
188
|
-
|
182
|
+
logger.debug("Pusher : sending event : #{payload}")
|
183
|
+
end
|
184
|
+
|
185
|
+
def send_channel_event(channel, event_name, data)
|
186
|
+
payload = {'channel' => channel, 'event' => event_name, 'data' => data}.to_json
|
187
|
+
@connection.send(payload)
|
188
|
+
logger.debug("Pusher : sending channel event : #{payload}")
|
189
189
|
end
|
190
190
|
|
191
191
|
protected
|
192
192
|
|
193
|
-
|
194
|
-
|
193
|
+
attr_reader :logger
|
194
|
+
|
195
|
+
def connect_internal
|
196
|
+
@connection = PusherWebSocket.new(@url, {
|
197
|
+
:ssl => @encrypted,
|
198
|
+
:cert_file => @cert_file,
|
199
|
+
:ssl_verify => @ssl_verify
|
200
|
+
})
|
201
|
+
|
202
|
+
logger.debug("Websocket connected")
|
203
|
+
|
204
|
+
loop do
|
205
|
+
msg = @connection.receive.first
|
206
|
+
next if msg.nil?
|
207
|
+
params = parser(msg)
|
208
|
+
next if params['socket_id'] && params['socket_id'] == self.socket_id
|
209
|
+
|
210
|
+
send_local_event(params['event'], params['data'], params['channel'])
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def send_local_event(event_name, event_data, channel_name=nil)
|
215
|
+
if channel_name
|
195
216
|
channel = @channels[channel_name]
|
196
|
-
if
|
217
|
+
if channel
|
197
218
|
channel.dispatch_with_all(event_name, event_data)
|
198
219
|
end
|
199
220
|
end
|
200
221
|
|
201
222
|
@global_channel.dispatch_with_all(event_name, event_data)
|
202
|
-
|
223
|
+
logger.debug("Pusher : event received : channel: #{channel_name}; event: #{event_name}")
|
203
224
|
end
|
204
225
|
|
205
226
|
def parser(data)
|
206
227
|
return data if data.is_a? Hash
|
207
228
|
return JSON.parse(data)
|
208
229
|
rescue => err
|
209
|
-
|
210
|
-
|
230
|
+
logger.warn(err)
|
231
|
+
logger.warn("Pusher : data attribute not valid JSON - you may wish to implement your own Pusher::Client.parser")
|
211
232
|
return data
|
212
233
|
end
|
213
234
|
|
@@ -16,6 +16,7 @@ module PusherClient
|
|
16
16
|
@frame ||= WebSocket::Frame::Incoming::Server.new(:version => @hs.version)
|
17
17
|
@socket = TCPSocket.new(@hs.host, @hs.port || 80)
|
18
18
|
@cert_file = params[:cert_file]
|
19
|
+
@logger = params[:logger] || PusherClient.logger
|
19
20
|
|
20
21
|
if params[:ssl] == true
|
21
22
|
ctx = OpenSSL::SSL::SSLContext.new
|
@@ -44,7 +45,7 @@ module PusherClient
|
|
44
45
|
@hs << data
|
45
46
|
|
46
47
|
if @hs.finished?
|
47
|
-
raise
|
48
|
+
raise @hs.error.to_s unless @hs.valid?
|
48
49
|
@handshaked = true
|
49
50
|
break
|
50
51
|
end
|
@@ -54,7 +55,11 @@ module PusherClient
|
|
54
55
|
def send(data, type = :text)
|
55
56
|
raise "no handshake!" unless @handshaked
|
56
57
|
|
57
|
-
data = WebSocket::Frame::Outgoing::
|
58
|
+
data = WebSocket::Frame::Outgoing::Client.new(
|
59
|
+
:version => @hs.version,
|
60
|
+
:data => data,
|
61
|
+
:type => type
|
62
|
+
).to_s
|
58
63
|
@socket.write data
|
59
64
|
@socket.flush
|
60
65
|
end
|
@@ -80,14 +85,18 @@ module PusherClient
|
|
80
85
|
end
|
81
86
|
messages
|
82
87
|
rescue IOError, Errno::EBADF => error
|
83
|
-
|
88
|
+
logger.debug error.message
|
84
89
|
[]
|
85
90
|
end
|
86
91
|
|
87
92
|
def close
|
88
93
|
@socket.close
|
89
94
|
rescue IOError => error
|
90
|
-
|
95
|
+
logger.debug error.message
|
91
96
|
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
attr_reader :logger
|
92
101
|
end
|
93
102
|
end
|
data/pusher-client.gemspec
CHANGED
@@ -21,10 +21,10 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.require_paths = ['lib']
|
22
22
|
s.licenses = ['MIT']
|
23
23
|
|
24
|
-
s.add_runtime_dependency 'websocket', '~> 1.
|
25
|
-
s.add_runtime_dependency 'json'
|
24
|
+
s.add_runtime_dependency 'websocket', '~> 1.1.2'
|
25
|
+
s.add_runtime_dependency 'json'
|
26
26
|
|
27
|
-
s.add_development_dependency "
|
27
|
+
s.add_development_dependency "rspec"
|
28
28
|
s.add_development_dependency "rake"
|
29
|
-
s.add_development_dependency "bundler"
|
29
|
+
s.add_development_dependency "bundler"
|
30
30
|
end
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require 'logger'
|
1
|
+
require 'spec_helper'
|
3
2
|
|
4
3
|
describe "A PusherClient::Channels collection" do
|
5
4
|
before do
|
@@ -7,26 +6,26 @@ describe "A PusherClient::Channels collection" do
|
|
7
6
|
end
|
8
7
|
|
9
8
|
it "should initialize empty" do
|
10
|
-
@channels.
|
11
|
-
@channels.size.
|
9
|
+
expect(@channels).to be_empty
|
10
|
+
expect(@channels.size).to eq(0)
|
12
11
|
end
|
13
12
|
|
14
13
|
it "should instantiate new channels added to it by name" do
|
15
14
|
@channels << 'TestChannel'
|
16
|
-
@channels.find('TestChannel').class.
|
15
|
+
expect(@channels.find('TestChannel').class).to eq(PusherClient::Channel)
|
17
16
|
end
|
18
17
|
|
19
18
|
it "should allow removal of channels by name" do
|
20
19
|
@channels << 'TestChannel'
|
21
|
-
@channels['TestChannel'].class.
|
20
|
+
expect(@channels['TestChannel'].class).to eq(PusherClient::Channel)
|
22
21
|
@channels.remove('TestChannel')
|
23
|
-
@channels.
|
22
|
+
expect(@channels).to be_empty
|
24
23
|
end
|
25
24
|
|
26
25
|
it "should not allow two channels of the same name" do
|
27
26
|
@channels << 'TestChannel'
|
28
27
|
@channels << 'TestChannel'
|
29
|
-
@channels.size.
|
28
|
+
expect(@channels.size).to eq(1)
|
30
29
|
end
|
31
30
|
|
32
31
|
end
|
@@ -38,16 +37,16 @@ describe "A PusherClient::Channel" do
|
|
38
37
|
end
|
39
38
|
|
40
39
|
it 'should not be subscribed by default' do
|
41
|
-
@channel.subscribed.
|
40
|
+
expect(@channel.subscribed).to be_false
|
42
41
|
end
|
43
42
|
|
44
43
|
it 'should not be global by default' do
|
45
|
-
@channel.global.
|
44
|
+
expect(@channel.global).to be_false
|
46
45
|
end
|
47
46
|
|
48
47
|
it 'can have procs bound to an event' do
|
49
48
|
@channel.bind('TestEvent') {}
|
50
|
-
@channel.callbacks.size.
|
49
|
+
expect(@channel.callbacks.size).to eq(1)
|
51
50
|
end
|
52
51
|
|
53
52
|
it 'should run callbacks when an event is dispatched' do
|
@@ -57,7 +56,7 @@ describe "A PusherClient::Channel" do
|
|
57
56
|
end
|
58
57
|
|
59
58
|
@channel.dispatch('TestEvent', {})
|
60
|
-
PusherClient.logger.test_messages.
|
59
|
+
expect(PusherClient.logger.test_messages).to include("Local callback running")
|
61
60
|
end
|
62
61
|
|
63
62
|
end
|
@@ -68,16 +67,16 @@ describe "A PusherClient::Socket" do
|
|
68
67
|
end
|
69
68
|
|
70
69
|
it 'should not connect when instantiated' do
|
71
|
-
@socket.connected.
|
70
|
+
expect(@socket.connected).to be_false
|
72
71
|
end
|
73
72
|
|
74
|
-
it 'should raise ArgumentError if TEST_APP_KEY is
|
75
|
-
|
73
|
+
it 'should raise ArgumentError if TEST_APP_KEY is an empty string' do
|
74
|
+
expect {
|
76
75
|
@broken_socket = PusherClient::Socket.new('')
|
77
|
-
}.
|
78
|
-
|
79
|
-
@broken_socket = PusherClient::Socket.new(
|
80
|
-
}.
|
76
|
+
}.to raise_error(ArgumentError)
|
77
|
+
expect {
|
78
|
+
@broken_socket = PusherClient::Socket.new(nil)
|
79
|
+
}.to raise_error(ArgumentError)
|
81
80
|
end
|
82
81
|
|
83
82
|
describe "...when connected" do
|
@@ -86,70 +85,71 @@ describe "A PusherClient::Socket" do
|
|
86
85
|
end
|
87
86
|
|
88
87
|
it 'should know its connected' do
|
89
|
-
@socket.connected.
|
88
|
+
expect(@socket.connected).to be_true
|
90
89
|
end
|
91
90
|
|
92
91
|
it 'should know its socket_id' do
|
93
|
-
@socket.socket_id.
|
92
|
+
expect(@socket.socket_id).to eq('123abc')
|
94
93
|
end
|
95
94
|
|
96
95
|
it 'should not be subscribed to its global channel' do
|
97
|
-
@socket.global_channel.subscribed.
|
96
|
+
expect(@socket.global_channel.subscribed).to be_false
|
98
97
|
end
|
99
98
|
|
100
99
|
it 'should subscribe to a channel' do
|
101
100
|
@channel = @socket.subscribe('testchannel')
|
102
|
-
@socket.channels['testchannel'].
|
103
|
-
@channel.subscribed.
|
101
|
+
expect(@socket.channels['testchannel']).to eq(@channel)
|
102
|
+
expect(@channel.subscribed).to be_true
|
104
103
|
end
|
105
104
|
|
106
105
|
it 'should unsubscribe from a channel' do
|
107
|
-
@
|
108
|
-
|
109
|
-
|
106
|
+
@socket.subscribe('testchannel')
|
107
|
+
@socket.unsubscribe('testchannel')
|
108
|
+
expect(PusherClient.logger.test_messages.last).to include('pusher:unsubscribe')
|
109
|
+
expect(@socket.channels['testchannel']).to be_nil
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'should subscribe to a private channel' do
|
113
113
|
@channel = @socket.subscribe('private-testchannel')
|
114
|
-
@socket.channels['private-testchannel'].
|
115
|
-
@channel.subscribed.
|
114
|
+
expect(@socket.channels['private-testchannel']).to eq(@channel)
|
115
|
+
expect(@channel.subscribed).to be_true
|
116
116
|
end
|
117
117
|
|
118
118
|
it 'should subscribe to a presence channel with user_id' do
|
119
119
|
@channel = @socket.subscribe('presence-testchannel', '123')
|
120
|
-
@socket.channels['presence-testchannel'].
|
121
|
-
@
|
122
|
-
@channel.subscribed.
|
120
|
+
expect(@socket.channels['presence-testchannel']).to eq(@channel)
|
121
|
+
expect(@channel.user_data).to eq('{"user_id":"123"}')
|
122
|
+
expect(@channel.subscribed).to be_true
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'should subscribe to a presence channel with custom channel_data' do
|
126
126
|
@channel = @socket.subscribe('presence-testchannel', :user_id => '123', :user_name => 'john')
|
127
|
-
@socket.channels['presence-testchannel'].
|
128
|
-
@
|
129
|
-
@channel.subscribed.
|
127
|
+
expect(@socket.channels['presence-testchannel']).to eq(@channel)
|
128
|
+
expect(@channel.user_data).to eq('{"user_id":"123","user_name":"john"}')
|
129
|
+
expect(@channel.subscribed).to be_true
|
130
130
|
end
|
131
131
|
|
132
132
|
it 'should allow binding of global events' do
|
133
133
|
@socket.bind('testevent') { |data| PusherClient.logger.test("testchannel received #{data}") }
|
134
|
-
@socket.global_channel.callbacks.has_key?('testevent').
|
134
|
+
expect(@socket.global_channel.callbacks.has_key?('testevent')).to be_true
|
135
135
|
end
|
136
136
|
|
137
137
|
it 'should trigger callbacks for global events' do
|
138
138
|
@socket.bind('globalevent') { |data| PusherClient.logger.test("Global event!") }
|
139
|
-
@socket.global_channel.callbacks.has_key?('globalevent').
|
139
|
+
expect(@socket.global_channel.callbacks.has_key?('globalevent')).to be_true
|
140
140
|
|
141
141
|
@socket.simulate_received('globalevent', 'some data', '')
|
142
|
-
PusherClient.logger.test_messages.last.
|
142
|
+
expect(PusherClient.logger.test_messages.last).to include('Global event!')
|
143
143
|
end
|
144
144
|
|
145
145
|
it 'should kill the connection thread when disconnect is called' do
|
146
146
|
@socket.disconnect
|
147
|
-
Thread.list.size.
|
147
|
+
expect(Thread.list.size).to eq(1)
|
148
148
|
end
|
149
149
|
|
150
150
|
it 'should not be connected after disconnecting' do
|
151
151
|
@socket.disconnect
|
152
|
-
@socket.connected.
|
152
|
+
expect(@socket.connected).to be_false
|
153
153
|
end
|
154
154
|
|
155
155
|
describe "when subscribed to a channel" do
|
@@ -159,7 +159,7 @@ describe "A PusherClient::Socket" do
|
|
159
159
|
|
160
160
|
it 'should allow binding of callbacks for the subscribed channel' do
|
161
161
|
@socket['testchannel'].bind('testevent') { |data| PusherClient.logger.test(data) }
|
162
|
-
@socket['testchannel'].callbacks.has_key?('testevent').
|
162
|
+
expect(@socket['testchannel'].callbacks.has_key?('testevent')).to be_true
|
163
163
|
end
|
164
164
|
|
165
165
|
it "should trigger channel callbacks when a message is received" do
|
@@ -169,11 +169,11 @@ describe "A PusherClient::Socket" do
|
|
169
169
|
|
170
170
|
# Simulate the first event
|
171
171
|
@socket.simulate_received('coming', 'Hello!', 'testchannel')
|
172
|
-
PusherClient.logger.test_messages.last.
|
172
|
+
expect(PusherClient.logger.test_messages.last).to include('Hello!')
|
173
173
|
|
174
174
|
# Simulate the second event
|
175
175
|
@socket.simulate_received('going', 'Goodbye!', 'testchannel')
|
176
|
-
PusherClient.logger.test_messages.last.
|
176
|
+
expect(PusherClient.logger.test_messages.last).to include('Goodbye!')
|
177
177
|
end
|
178
178
|
|
179
179
|
end
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pusher-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.5.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Pusher
|
@@ -10,72 +9,78 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2014-04-15 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: websocket
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
18
|
- - ~>
|
21
19
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
20
|
+
version: 1.1.2
|
23
21
|
type: :runtime
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
25
|
- - ~>
|
29
26
|
- !ruby/object:Gem::Version
|
30
|
-
version: 1.
|
27
|
+
version: 1.1.2
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
|
-
name:
|
29
|
+
name: json
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
|
-
- -
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
37
47
|
- !ruby/object:Gem::Version
|
38
48
|
version: '0'
|
39
49
|
type: :development
|
40
50
|
prerelease: false
|
41
51
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
52
|
requirements:
|
44
|
-
- -
|
53
|
+
- - '>='
|
45
54
|
- !ruby/object:Gem::Version
|
46
55
|
version: '0'
|
47
56
|
- !ruby/object:Gem::Dependency
|
48
57
|
name: rake
|
49
58
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
59
|
requirements:
|
52
|
-
- -
|
60
|
+
- - '>='
|
53
61
|
- !ruby/object:Gem::Version
|
54
62
|
version: '0'
|
55
63
|
type: :development
|
56
64
|
prerelease: false
|
57
65
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
66
|
requirements:
|
60
|
-
- -
|
67
|
+
- - '>='
|
61
68
|
- !ruby/object:Gem::Version
|
62
69
|
version: '0'
|
63
70
|
- !ruby/object:Gem::Dependency
|
64
71
|
name: bundler
|
65
72
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
73
|
requirements:
|
68
|
-
- -
|
74
|
+
- - '>='
|
69
75
|
- !ruby/object:Gem::Version
|
70
|
-
version: '
|
76
|
+
version: '0'
|
71
77
|
type: :development
|
72
78
|
prerelease: false
|
73
79
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
80
|
requirements:
|
76
|
-
- -
|
81
|
+
- - '>='
|
77
82
|
- !ruby/object:Gem::Version
|
78
|
-
version: '
|
83
|
+
version: '0'
|
79
84
|
description: Client for consuming WebSockets from http://pusher.com
|
80
85
|
email:
|
81
86
|
- support@pusher.com
|
@@ -88,6 +93,7 @@ files:
|
|
88
93
|
- .document
|
89
94
|
- .gitignore
|
90
95
|
- .travis.yml
|
96
|
+
- CHANGELOG.md
|
91
97
|
- Gemfile
|
92
98
|
- LICENSE.txt
|
93
99
|
- README.rdoc
|
@@ -104,41 +110,32 @@ files:
|
|
104
110
|
- lib/pusher-client/version.rb
|
105
111
|
- lib/pusher-client/websocket.rb
|
106
112
|
- pusher-client.gemspec
|
107
|
-
-
|
108
|
-
-
|
109
|
-
- test/teststrap.rb
|
113
|
+
- spec/pusherclient_spec.rb
|
114
|
+
- spec/spec_helper.rb
|
110
115
|
homepage: http://github.com/pusher/pusher-ruby-client
|
111
116
|
licenses:
|
112
117
|
- MIT
|
118
|
+
metadata: {}
|
113
119
|
post_install_message:
|
114
120
|
rdoc_options: []
|
115
121
|
require_paths:
|
116
122
|
- lib
|
117
123
|
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
-
none: false
|
119
124
|
requirements:
|
120
|
-
- -
|
125
|
+
- - '>='
|
121
126
|
- !ruby/object:Gem::Version
|
122
127
|
version: '0'
|
123
|
-
segments:
|
124
|
-
- 0
|
125
|
-
hash: -363523268946277982
|
126
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
-
none: false
|
128
129
|
requirements:
|
129
|
-
- -
|
130
|
+
- - '>='
|
130
131
|
- !ruby/object:Gem::Version
|
131
132
|
version: '0'
|
132
|
-
segments:
|
133
|
-
- 0
|
134
|
-
hash: -363523268946277982
|
135
133
|
requirements: []
|
136
134
|
rubyforge_project:
|
137
|
-
rubygems_version:
|
135
|
+
rubygems_version: 2.0.14
|
138
136
|
signing_key:
|
139
|
-
specification_version:
|
137
|
+
specification_version: 4
|
140
138
|
summary: Client for consuming WebSockets from http://pusher.com
|
141
139
|
test_files:
|
142
|
-
-
|
143
|
-
-
|
144
|
-
- test/teststrap.rb
|
140
|
+
- spec/pusherclient_spec.rb
|
141
|
+
- spec/spec_helper.rb
|
data/test/test.watchr
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
ENV["WATCHR"] = "1"
|
2
|
-
system 'clear'
|
3
|
-
puts "Watchr: Ready! :-)"
|
4
|
-
|
5
|
-
def notify_send(result)
|
6
|
-
#title = "Watchr Test Results"
|
7
|
-
if result.include?("FAILED") or result.include?("ERROR")
|
8
|
-
title = "FAIL"
|
9
|
-
image = "~/.autotest_images/fail.png"
|
10
|
-
message = "One or more tests have failed"
|
11
|
-
else
|
12
|
-
title = "PASS"
|
13
|
-
image = "~/.autotest_images/pass.png"
|
14
|
-
message = "All tests pass"
|
15
|
-
end
|
16
|
-
|
17
|
-
options = "-c Watchr --icon '#{File.expand_path(image)}' '#{title}' '#{message}' --urgency=critical"
|
18
|
-
system %(notify-send #{options} &)
|
19
|
-
end
|
20
|
-
|
21
|
-
def run(cmd)
|
22
|
-
puts(cmd)
|
23
|
-
`#{cmd}`
|
24
|
-
end
|
25
|
-
|
26
|
-
def run_all_tests
|
27
|
-
system('clear')
|
28
|
-
result = run "bacon test/*_test.rb"
|
29
|
-
notify_send result
|
30
|
-
puts result
|
31
|
-
end
|
32
|
-
|
33
|
-
def run_suite
|
34
|
-
run_all_tests
|
35
|
-
end
|
36
|
-
|
37
|
-
watch('test/teststrap\.rb') { run_all_tests }
|
38
|
-
watch('test/factories\.rb') { run_all_tests }
|
39
|
-
watch('test/.*_test.*\.rb') { run_all_tests }
|
40
|
-
watch('lib/*\.rb') { run_all_tests }
|
41
|
-
watch('lib/.*/*\.rb') { run_all_tests }
|
42
|
-
|
43
|
-
# Ctrl-\
|
44
|
-
Signal.trap 'QUIT' do
|
45
|
-
puts " --- Running all tests ---\n\n"
|
46
|
-
run_all_tests
|
47
|
-
end
|
48
|
-
|
49
|
-
@interrupted = false
|
50
|
-
|
51
|
-
# Ctrl-C
|
52
|
-
Signal.trap 'INT' do
|
53
|
-
if @interrupted then
|
54
|
-
@wants_to_quit = true
|
55
|
-
abort("\n")
|
56
|
-
else
|
57
|
-
puts "Interrupt a second time to quit"
|
58
|
-
@interrupted = true
|
59
|
-
Kernel.sleep 1.5
|
60
|
-
# raise Interrupt, nil # let the run loop catch it
|
61
|
-
run_suite
|
62
|
-
end
|
63
|
-
end
|