pusher_rails 0.2.0 → 0.2.2
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.
- data/CHANGELOG.md +9 -0
- data/README.md +9 -9
- data/pusher_rails.gemspec +2 -2
- data/vendor/assets/javascripts/backpusher.js +10 -58
- data/vendor/assets/javascripts/pusher.js +506 -388
- metadata +11 -6
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
=====================
|
3
3
|
|
4
4
|
Adds:
|
5
|
-
- [pusher-gem v0.9.
|
6
|
-
- [pusher.js v1.
|
7
|
-
- [backpusher.js](https://github.com/pusher/backpusher
|
5
|
+
- [pusher-gem v0.9.2](https://github.com/pusher/pusher-gem/tree/v0.9.2)
|
6
|
+
- [pusher.js v1.12.0](https://github.com/pusher/pusher-js/tree/v1.12.0)
|
7
|
+
- [backpusher.js](https://github.com/pusher/backpusher)
|
8
8
|
|
9
9
|
This pulls in the *pusher-gem* as well as adding *pusher.js* and *backpusher.js* to the assets pipeline of your Rails 3.1+ app.
|
10
10
|
|
@@ -21,16 +21,16 @@ Licenses
|
|
21
21
|
========
|
22
22
|
|
23
23
|
/*!
|
24
|
-
* Pusher JavaScript Library v1.
|
24
|
+
* Pusher JavaScript Library v1.12.0
|
25
25
|
* http://pusherapp.com/
|
26
26
|
*
|
27
27
|
* Copyright 2011, Pusher
|
28
28
|
* Released under the MIT licence.
|
29
29
|
*/
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
// Backpusher.js 0.0.2
|
32
|
+
// (c) 2011-2012 Pusher.
|
33
|
+
// Backpusher may be freely distributed under the MIT license.
|
34
|
+
// For all details and documentation:
|
35
|
+
// http://github.com/pusher/backpusher
|
36
36
|
|
data/pusher_rails.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'pusher_rails'
|
6
|
-
s.version = '0.2.
|
6
|
+
s.version = '0.2.2'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["David Grandinetti"]
|
9
9
|
s.email = ["dave@wegoto12.com"]
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.description = 'Adds pusher.js/backpusher.js to the asset pipeline and pusher-gem to to your app.'
|
12
12
|
s.homepage = 'https://github.com/dbgrandi/pusher_rails'
|
13
13
|
|
14
|
-
s.add_dependency "pusher", "~> 0.9.
|
14
|
+
s.add_dependency "pusher", "~> 0.9.2"
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.require_paths = ["lib"]
|
@@ -1,5 +1,5 @@
|
|
1
|
-
// Backpusher.js 0.0.
|
2
|
-
// (c) 2011 Pusher.
|
1
|
+
// Backpusher.js 0.0.2
|
2
|
+
// (c) 2011-2012 Pusher.
|
3
3
|
// Backpusher may be freely distributed under the MIT license.
|
4
4
|
// For all details and documentation:
|
5
5
|
// http://github.com/pusher/backpusher
|
@@ -92,65 +92,17 @@
|
|
92
92
|
}
|
93
93
|
};
|
94
94
|
|
95
|
-
//
|
96
|
-
var
|
97
|
-
'create': 'POST',
|
98
|
-
'update': 'PUT',
|
99
|
-
'delete': 'DELETE',
|
100
|
-
'read' : 'GET'
|
101
|
-
};
|
102
|
-
|
95
|
+
// Add socket ID to every Backbone.sync request
|
96
|
+
var origBackboneSync = Backbone.sync;
|
103
97
|
Backbone.sync = function(method, model, options) {
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
type: type,
|
109
|
-
dataType: 'json'
|
110
|
-
}, options);
|
111
|
-
|
112
|
-
if (!(model && model.url)) {
|
113
|
-
throw new Error("A 'url' property or function must be specified");
|
114
|
-
}
|
115
|
-
|
116
|
-
if (!params.url) {
|
117
|
-
params.url = _.isFunction(model.url) ? model.url() : model.url;
|
118
|
-
params.url += '?socket_id=' + Backbone.pusher_socket_id;
|
119
|
-
}
|
120
|
-
|
121
|
-
// Ensure that we have the appropriate request data.
|
122
|
-
if (!params.data && model && (method == 'create' || method == 'update')) {
|
123
|
-
params.contentType = 'application/json';
|
124
|
-
params.data = JSON.stringify(model.toJSON());
|
125
|
-
}
|
126
|
-
|
127
|
-
// For older servers, emulate JSON by encoding the request into an HTML-form.
|
128
|
-
if (Backbone.emulateJSON) {
|
129
|
-
params.contentType = 'application/x-www-form-urlencoded';
|
130
|
-
params.data = params.data ? {model : params.data} : {};
|
131
|
-
}
|
132
|
-
|
133
|
-
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
|
134
|
-
// And an `X-HTTP-Method-Override` header.
|
135
|
-
if (Backbone.emulateHTTP) {
|
136
|
-
if (type === 'PUT' || type === 'DELETE') {
|
137
|
-
if (Backbone.emulateJSON) params.data._method = type;
|
138
|
-
params.type = 'POST';
|
139
|
-
params.beforeSend = function(xhr) {
|
140
|
-
xhr.setRequestHeader('X-HTTP-Method-Override', type);
|
141
|
-
};
|
142
|
-
}
|
143
|
-
}
|
144
|
-
|
145
|
-
// Don't process data on a non-GET request.
|
146
|
-
if (params.type !== 'GET' && !Backbone.emulateJSON) {
|
147
|
-
params.processData = false;
|
148
|
-
}
|
98
|
+
options.headers = _.extend(
|
99
|
+
{ 'X-Pusher-Socket-ID': Backbone.pusher_socket_id },
|
100
|
+
options.headers
|
101
|
+
);
|
149
102
|
|
150
|
-
|
151
|
-
return $.ajax(params);
|
103
|
+
return origBackboneSync(method, model, options);
|
152
104
|
};
|
153
105
|
|
154
106
|
// Export:
|
155
107
|
exports.Backpusher = Backpusher;
|
156
|
-
})((typeof exports !== 'undefined' ? exports : this));
|
108
|
+
})((typeof exports !== 'undefined' ? exports : this));
|
@@ -1,206 +1,211 @@
|
|
1
1
|
/*!
|
2
|
-
* Pusher JavaScript Library v1.
|
2
|
+
* Pusher JavaScript Library v1.12.0
|
3
3
|
* http://pusherapp.com/
|
4
4
|
*
|
5
5
|
* Copyright 2011, Pusher
|
6
6
|
* Released under the MIT licence.
|
7
7
|
*/
|
8
8
|
|
9
|
-
|
10
|
-
Function.prototype.scopedTo
|
11
|
-
|
12
|
-
|
13
|
-
return
|
14
|
-
.
|
9
|
+
;(function() {
|
10
|
+
if (Function.prototype.scopedTo === undefined) {
|
11
|
+
Function.prototype.scopedTo = function(context, args) {
|
12
|
+
var f = this;
|
13
|
+
return function() {
|
14
|
+
return f.apply(context, Array.prototype.slice.call(args || [])
|
15
|
+
.concat(Array.prototype.slice.call(arguments)));
|
16
|
+
};
|
15
17
|
};
|
16
|
-
}
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
18
|
+
}
|
19
|
+
|
20
|
+
var Pusher = function(app_key, options) {
|
21
|
+
this.options = options || {};
|
22
|
+
this.key = app_key;
|
23
|
+
this.channels = new Pusher.Channels();
|
24
|
+
this.global_emitter = new Pusher.EventsDispatcher()
|
25
|
+
|
26
|
+
var self = this;
|
27
|
+
|
28
|
+
this.checkAppKey();
|
29
|
+
|
30
|
+
this.connection = new Pusher.Connection(this.key, this.options);
|
31
|
+
|
32
|
+
// Setup / teardown connection
|
33
|
+
this.connection
|
34
|
+
.bind('connected', function() {
|
35
|
+
self.subscribeAll();
|
36
|
+
})
|
37
|
+
.bind('message', function(params) {
|
38
|
+
var internal = (params.event.indexOf('pusher_internal:') === 0);
|
39
|
+
if (params.channel) {
|
40
|
+
var channel;
|
41
|
+
if (channel = self.channel(params.channel)) {
|
42
|
+
channel.emit(params.event, params.data);
|
43
|
+
}
|
42
44
|
}
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
});
|
45
|
+
// Emit globaly [deprecated]
|
46
|
+
if (!internal) self.global_emitter.emit(params.event, params.data);
|
47
|
+
})
|
48
|
+
.bind('disconnected', function() {
|
49
|
+
self.channels.disconnect();
|
50
|
+
})
|
51
|
+
.bind('error', function(err) {
|
52
|
+
Pusher.warn('Error', err);
|
53
|
+
});
|
53
54
|
|
54
|
-
|
55
|
+
Pusher.instances.push(this);
|
55
56
|
|
56
|
-
|
57
|
-
};
|
58
|
-
Pusher.instances = [];
|
59
|
-
Pusher.prototype = {
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
if (Pusher.isReady) self.connect();
|
58
|
+
};
|
59
|
+
Pusher.instances = [];
|
60
|
+
Pusher.prototype = {
|
61
|
+
channel: function(name) {
|
62
|
+
return this.channels.find(name);
|
63
|
+
},
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
65
|
+
connect: function() {
|
66
|
+
this.connection.connect();
|
67
|
+
},
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
69
|
+
disconnect: function() {
|
70
|
+
this.connection.disconnect();
|
71
|
+
},
|
71
72
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
bind: function(event_name, callback) {
|
74
|
+
this.global_emitter.bind(event_name, callback);
|
75
|
+
return this;
|
76
|
+
},
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
bind_all: function(callback) {
|
79
|
+
this.global_emitter.bind_all(callback);
|
80
|
+
return this;
|
81
|
+
},
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
subscribeAll: function() {
|
84
|
+
var channel;
|
85
|
+
for (channelName in this.channels.channels) {
|
86
|
+
if (this.channels.channels.hasOwnProperty(channelName)) {
|
87
|
+
this.subscribe(channelName);
|
88
|
+
}
|
87
89
|
}
|
88
|
-
}
|
89
|
-
},
|
90
|
+
},
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
92
|
+
subscribe: function(channel_name) {
|
93
|
+
var self = this;
|
94
|
+
var channel = this.channels.add(channel_name, this);
|
95
|
+
|
96
|
+
if (this.connection.state === 'connected') {
|
97
|
+
channel.authorize(this.connection.socket_id, this.options, function(err, data) {
|
98
|
+
if (err) {
|
99
|
+
channel.emit('pusher:subscription_error', data);
|
100
|
+
} else {
|
101
|
+
self.send_event('pusher:subscribe', {
|
102
|
+
channel: channel_name,
|
103
|
+
auth: data.auth,
|
104
|
+
channel_data: data.channel_data
|
105
|
+
});
|
106
|
+
}
|
107
|
+
});
|
108
|
+
}
|
109
|
+
return channel;
|
110
|
+
},
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
112
|
+
unsubscribe: function(channel_name) {
|
113
|
+
this.channels.remove(channel_name);
|
114
|
+
if (this.connection.state === 'connected') {
|
115
|
+
this.send_event('pusher:unsubscribe', {
|
116
|
+
channel: channel_name
|
117
|
+
});
|
118
|
+
}
|
119
|
+
},
|
118
120
|
|
119
|
-
|
120
|
-
|
121
|
-
|
121
|
+
send_event: function(event_name, data, channel) {
|
122
|
+
return this.connection.send_event(event_name, data, channel);
|
123
|
+
},
|
122
124
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
}
|
127
|
-
}
|
128
|
-
};
|
129
|
-
|
130
|
-
Pusher.Util = {
|
131
|
-
extend: function extend(target, extensions) {
|
132
|
-
for (var property in extensions) {
|
133
|
-
if (extensions[property] && extensions[property].constructor &&
|
134
|
-
extensions[property].constructor === Object) {
|
135
|
-
target[property] = extend(target[property] || {}, extensions[property]);
|
136
|
-
} else {
|
137
|
-
target[property] = extensions[property];
|
125
|
+
checkAppKey: function() {
|
126
|
+
if(this.key === null || this.key === undefined) {
|
127
|
+
Pusher.warn('Warning', 'You must pass your app key when you instantiate Pusher.');
|
138
128
|
}
|
139
129
|
}
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
} else {
|
149
|
-
if (window['JSON'] == undefined) {
|
150
|
-
m.push(arguments[i].toString());
|
130
|
+
};
|
131
|
+
|
132
|
+
Pusher.Util = {
|
133
|
+
extend: function extend(target, extensions) {
|
134
|
+
for (var property in extensions) {
|
135
|
+
if (extensions[property] && extensions[property].constructor &&
|
136
|
+
extensions[property].constructor === Object) {
|
137
|
+
target[property] = extend(target[property] || {}, extensions[property]);
|
151
138
|
} else {
|
152
|
-
|
139
|
+
target[property] = extensions[property];
|
153
140
|
}
|
154
141
|
}
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
}
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
142
|
+
return target;
|
143
|
+
},
|
144
|
+
|
145
|
+
stringify: function stringify() {
|
146
|
+
var m = ["Pusher"]
|
147
|
+
for (var i = 0; i < arguments.length; i++){
|
148
|
+
if (typeof arguments[i] === "string") {
|
149
|
+
m.push(arguments[i])
|
150
|
+
} else {
|
151
|
+
if (window['JSON'] == undefined) {
|
152
|
+
m.push(arguments[i].toString());
|
153
|
+
} else {
|
154
|
+
m.push(JSON.stringify(arguments[i]))
|
155
|
+
}
|
156
|
+
}
|
157
|
+
};
|
158
|
+
return m.join(" : ")
|
159
|
+
},
|
160
|
+
|
161
|
+
arrayIndexOf: function(array, item) { // MSIE doesn't have array.indexOf
|
162
|
+
var nativeIndexOf = Array.prototype.indexOf;
|
163
|
+
if (array == null) return -1;
|
164
|
+
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
|
165
|
+
for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
|
166
|
+
return -1;
|
167
|
+
}
|
168
|
+
};
|
169
|
+
|
170
|
+
// To receive log output provide a Pusher.log function, for example
|
171
|
+
// Pusher.log = function(m){console.log(m)}
|
172
|
+
Pusher.debug = function() {
|
178
173
|
if (!Pusher.log) return
|
179
|
-
Pusher.log(Pusher.Util.stringify.apply(this, arguments))
|
174
|
+
Pusher.log(Pusher.Util.stringify.apply(this, arguments))
|
180
175
|
}
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
Pusher.
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
Pusher
|
191
|
-
Pusher.
|
192
|
-
|
193
|
-
Pusher.
|
194
|
-
Pusher.
|
195
|
-
Pusher.
|
196
|
-
|
197
|
-
Pusher.
|
198
|
-
Pusher.
|
199
|
-
Pusher.
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
176
|
+
Pusher.warn = function() {
|
177
|
+
if (window.console && window.console.warn) {
|
178
|
+
window.console.warn(Pusher.Util.stringify.apply(this, arguments));
|
179
|
+
} else {
|
180
|
+
if (!Pusher.log) return
|
181
|
+
Pusher.log(Pusher.Util.stringify.apply(this, arguments));
|
182
|
+
}
|
183
|
+
};
|
184
|
+
|
185
|
+
// Pusher defaults
|
186
|
+
Pusher.VERSION = '1.12.0';
|
187
|
+
|
188
|
+
Pusher.host = 'ws.pusherapp.com';
|
189
|
+
Pusher.ws_port = 80;
|
190
|
+
Pusher.wss_port = 443;
|
191
|
+
Pusher.channel_auth_endpoint = '/pusher/auth';
|
192
|
+
Pusher.cdn_http = 'http://js.pusher.com/'
|
193
|
+
Pusher.cdn_https = 'https://d3dy5gmtp8yhk7.cloudfront.net/'
|
194
|
+
Pusher.dependency_suffix = '';
|
195
|
+
Pusher.channel_auth_transport = 'ajax';
|
196
|
+
Pusher.activity_timeout = 120000;
|
197
|
+
Pusher.pong_timeout = 30000;
|
198
|
+
|
199
|
+
Pusher.isReady = false;
|
200
|
+
Pusher.ready = function() {
|
201
|
+
Pusher.isReady = true;
|
202
|
+
for (var i = 0, l = Pusher.instances.length; i < l; i++) {
|
203
|
+
Pusher.instances[i].connect();
|
204
|
+
}
|
205
|
+
};
|
206
|
+
|
207
|
+
this.Pusher = Pusher;
|
208
|
+
}).call(this);
|
204
209
|
|
205
210
|
;(function() {
|
206
211
|
/* Abstract event binding
|
@@ -230,7 +235,7 @@ Example:
|
|
230
235
|
this.callbacks[event_name].push(callback);
|
231
236
|
return this;// chainable
|
232
237
|
};
|
233
|
-
|
238
|
+
|
234
239
|
EventsDispatcher.prototype.unbind = function(eventName, callback) {
|
235
240
|
if(this.callbacks[eventName]) {
|
236
241
|
var index = Pusher.Util.arrayIndexOf(this.callbacks[eventName], callback);
|
@@ -307,6 +312,11 @@ Example:
|
|
307
312
|
var stateCallbacks = this.stateActions;
|
308
313
|
|
309
314
|
if (prevState && (Pusher.Util.arrayIndexOf(this.transitions[prevState], nextState) == -1)) {
|
315
|
+
this.emit('invalid_transition_attempt', {
|
316
|
+
oldState: prevState,
|
317
|
+
newState: nextState
|
318
|
+
});
|
319
|
+
|
310
320
|
throw new Error('Invalid transition [' + prevState + ' to ' + nextState + ']');
|
311
321
|
}
|
312
322
|
|
@@ -350,6 +360,7 @@ Example:
|
|
350
360
|
A little bauble to interface with window.navigator.onLine,
|
351
361
|
window.ononline and window.onoffline. Easier to mock.
|
352
362
|
*/
|
363
|
+
|
353
364
|
var NetInfo = function() {
|
354
365
|
var self = this;
|
355
366
|
Pusher.EventsDispatcher.call(this);
|
@@ -376,7 +387,7 @@ Example:
|
|
376
387
|
};
|
377
388
|
|
378
389
|
Pusher.Util.extend(NetInfo.prototype, Pusher.EventsDispatcher.prototype);
|
379
|
-
|
390
|
+
|
380
391
|
this.Pusher.NetInfo = NetInfo;
|
381
392
|
}).call(this);
|
382
393
|
|
@@ -431,7 +442,7 @@ Example:
|
|
431
442
|
this.netInfo.bind('online', function(){
|
432
443
|
if (self._machine.is('waiting')) {
|
433
444
|
self._machine.transition('connecting');
|
434
|
-
|
445
|
+
updateState('connecting');
|
435
446
|
}
|
436
447
|
});
|
437
448
|
|
@@ -452,8 +463,6 @@ Example:
|
|
452
463
|
|
453
464
|
// define the state machine that runs the connection
|
454
465
|
this._machine = new Pusher.Machine('initialized', machineTransitions, {
|
455
|
-
|
456
|
-
// TODO: Use the constructor for this.
|
457
466
|
initializedPre: function() {
|
458
467
|
self.compulsorySecure = self.options.encrypted;
|
459
468
|
|
@@ -469,16 +478,18 @@ Example:
|
|
469
478
|
self.emit('connecting_in', self.connectionWait);
|
470
479
|
}
|
471
480
|
|
472
|
-
if (self.netInfo.isOnLine()
|
473
|
-
|
481
|
+
if (self.netInfo.isOnLine() && self.connectionAttempts <= 4) {
|
482
|
+
updateState('connecting');
|
474
483
|
} else {
|
475
|
-
|
484
|
+
updateState('unavailable');
|
476
485
|
}
|
477
486
|
|
478
|
-
|
487
|
+
// When in the unavailable state we attempt to connect, but don't
|
488
|
+
// broadcast that fact
|
489
|
+
if (self.netInfo.isOnLine()) {
|
479
490
|
self._waitingTimer = setTimeout(function() {
|
480
491
|
self._machine.transition('connecting');
|
481
|
-
},
|
492
|
+
}, connectionDelay());
|
482
493
|
}
|
483
494
|
},
|
484
495
|
|
@@ -491,7 +502,7 @@ Example:
|
|
491
502
|
// state even when offline.
|
492
503
|
if (self.netInfo.isOnLine() === false) {
|
493
504
|
self._machine.transition('waiting');
|
494
|
-
|
505
|
+
updateState('unavailable');
|
495
506
|
|
496
507
|
return;
|
497
508
|
}
|
@@ -513,6 +524,7 @@ Example:
|
|
513
524
|
|
514
525
|
connectingExit: function() {
|
515
526
|
clearTimeout(self._connectingTimer);
|
527
|
+
self.socket.onopen = undefined; // unbind to avoid open events that are no longer relevant
|
516
528
|
},
|
517
529
|
|
518
530
|
connectingToWaiting: function() {
|
@@ -538,6 +550,7 @@ Example:
|
|
538
550
|
|
539
551
|
openExit: function() {
|
540
552
|
clearTimeout(self._openTimer);
|
553
|
+
self.socket.onmessage = undefined; // unbind to avoid messages that are no longer relevant
|
541
554
|
},
|
542
555
|
|
543
556
|
openToWaiting: function() {
|
@@ -556,17 +569,18 @@ Example:
|
|
556
569
|
self.socket.onclose = transitionToWaiting;
|
557
570
|
|
558
571
|
resetConnectionParameters(self);
|
572
|
+
self.connectedAt = new Date().getTime();
|
559
573
|
|
560
574
|
resetActivityCheck();
|
561
575
|
},
|
562
576
|
|
563
577
|
connectedPost: function() {
|
564
|
-
|
578
|
+
updateState('connected');
|
565
579
|
},
|
566
580
|
|
567
581
|
connectedExit: function() {
|
568
582
|
stopActivityCheck();
|
569
|
-
|
583
|
+
updateState('disconnected');
|
570
584
|
},
|
571
585
|
|
572
586
|
impermanentlyClosingPost: function() {
|
@@ -591,8 +605,12 @@ Example:
|
|
591
605
|
},
|
592
606
|
|
593
607
|
failedPre: function() {
|
594
|
-
|
608
|
+
updateState('failed');
|
595
609
|
Pusher.debug('WebSockets are not available in this browser.');
|
610
|
+
},
|
611
|
+
|
612
|
+
permanentlyClosedPost: function() {
|
613
|
+
updateState('disconnected');
|
596
614
|
}
|
597
615
|
});
|
598
616
|
|
@@ -633,7 +651,11 @@ Example:
|
|
633
651
|
protocol = 'wss://';
|
634
652
|
}
|
635
653
|
|
636
|
-
|
654
|
+
var flash = (Pusher.TransportType === "flash") ? "true" : "false";
|
655
|
+
|
656
|
+
return protocol + Pusher.host + ':' + port + '/app/' + key + '?protocol=5&client=js'
|
657
|
+
+ '&version=' + Pusher.VERSION
|
658
|
+
+ '&flash=' + flash;
|
637
659
|
}
|
638
660
|
|
639
661
|
// callback for close and retry. Used on timeouts.
|
@@ -657,6 +679,25 @@ Example:
|
|
657
679
|
if (self._activityTimer) { clearTimeout(self._activityTimer); }
|
658
680
|
}
|
659
681
|
|
682
|
+
// Returns the delay before the next connection attempt should be made
|
683
|
+
//
|
684
|
+
// This function guards against attempting to connect more frequently than
|
685
|
+
// once every second
|
686
|
+
//
|
687
|
+
function connectionDelay() {
|
688
|
+
var delay = self.connectionWait;
|
689
|
+
if (delay === 0) {
|
690
|
+
if (self.connectedAt) {
|
691
|
+
var t = 1000;
|
692
|
+
var connectedFor = new Date().getTime() - self.connectedAt;
|
693
|
+
if (connectedFor < t) {
|
694
|
+
delay = t - connectedFor;
|
695
|
+
}
|
696
|
+
}
|
697
|
+
}
|
698
|
+
return delay;
|
699
|
+
}
|
700
|
+
|
660
701
|
/*-----------------------------------------------
|
661
702
|
WebSocket Callbacks
|
662
703
|
-----------------------------------------------*/
|
@@ -666,28 +707,40 @@ Example:
|
|
666
707
|
self._machine.transition('open');
|
667
708
|
};
|
668
709
|
|
710
|
+
function handleCloseCode(code, message) {
|
711
|
+
// first inform the end-developer of this error
|
712
|
+
self.emit('error', {type: 'PusherError', data: {code: code, message: message}});
|
713
|
+
|
714
|
+
if (code === 4000) {
|
715
|
+
// SSL only app
|
716
|
+
self.compulsorySecure = true;
|
717
|
+
self.connectionSecure = true;
|
718
|
+
self.options.encrypted = true;
|
719
|
+
|
720
|
+
self._machine.transition('impermanentlyClosing')
|
721
|
+
} else if (code < 4100) {
|
722
|
+
// Permentently close connection
|
723
|
+
self._machine.transition('permanentlyClosing')
|
724
|
+
} else if (code < 4200) {
|
725
|
+
// Backoff before reconnecting
|
726
|
+
self.connectionWait = 1000;
|
727
|
+
self._machine.transition('waiting')
|
728
|
+
} else if (code < 4300) {
|
729
|
+
// Reconnect immediately
|
730
|
+
self._machine.transition('impermanentlyClosing')
|
731
|
+
} else {
|
732
|
+
// Unknown error
|
733
|
+
self._machine.transition('permanentlyClosing')
|
734
|
+
}
|
735
|
+
}
|
736
|
+
|
669
737
|
function ws_onMessageOpen(event) {
|
670
738
|
var params = parseWebSocketEvent(event);
|
671
739
|
if (params !== undefined) {
|
672
740
|
if (params.event === 'pusher:connection_established') {
|
673
741
|
self._machine.transition('connected', params.data.socket_id);
|
674
742
|
} else if (params.event === 'pusher:error') {
|
675
|
-
|
676
|
-
self.emit('error', {type: 'PusherError', data: params.data});
|
677
|
-
|
678
|
-
switch (params.data.code) {
|
679
|
-
case 4000:
|
680
|
-
Pusher.warn(params.data.message);
|
681
|
-
|
682
|
-
self.compulsorySecure = true;
|
683
|
-
self.connectionSecure = true;
|
684
|
-
self.options.encrypted = true;
|
685
|
-
break;
|
686
|
-
case 4001:
|
687
|
-
// App not found by key - close connection
|
688
|
-
self._machine.transition('permanentlyClosing');
|
689
|
-
break;
|
690
|
-
}
|
743
|
+
handleCloseCode(params.data.code, params.data.message)
|
691
744
|
}
|
692
745
|
}
|
693
746
|
}
|
@@ -753,19 +806,21 @@ Example:
|
|
753
806
|
self._machine.transition('impermanentlyClosing');
|
754
807
|
}
|
755
808
|
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
809
|
+
// Updates the public state information exposed by connection
|
810
|
+
//
|
811
|
+
// This is distinct from the internal state information used by _machine
|
812
|
+
// to manage the connection
|
813
|
+
//
|
814
|
+
function updateState(newState, data) {
|
761
815
|
var prevState = self.state;
|
762
|
-
|
763
816
|
self.state = newState;
|
764
817
|
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
818
|
+
// Only emit when the state changes
|
819
|
+
if (prevState !== newState) {
|
820
|
+
Pusher.debug('State changed', prevState + ' -> ' + newState);
|
821
|
+
self.emit('state_change', {previous: prevState, current: newState});
|
822
|
+
self.emit(newState, data);
|
823
|
+
}
|
769
824
|
}
|
770
825
|
};
|
771
826
|
|
@@ -785,14 +840,24 @@ Example:
|
|
785
840
|
}
|
786
841
|
// user re-opening connection after closing it
|
787
842
|
else if(this._machine.is("permanentlyClosed")) {
|
843
|
+
resetConnectionParameters(this);
|
788
844
|
this._machine.transition('waiting');
|
789
845
|
}
|
790
846
|
};
|
791
847
|
|
792
848
|
Connection.prototype.send = function(data) {
|
793
849
|
if (this._machine.is('connected')) {
|
794
|
-
|
795
|
-
|
850
|
+
// Bug in iOS (reproduced in 5.0.1) Mobile Safari:
|
851
|
+
// 1. Open page/tab, connect WS, get some data.
|
852
|
+
// 2. Switch tab or close Mobile Safari and wait for WS connection to get closed (probably by server).
|
853
|
+
// 3. Switch back to tab or open Mobile Safari and Mobile Safari crashes.
|
854
|
+
// The problem is that WS tries to send data on closed WS connection before it realises it is closed.
|
855
|
+
// The timeout means that by the time the send happens, the WS readyState correctly reflects closed state.
|
856
|
+
var self = this;
|
857
|
+
setTimeout(function() {
|
858
|
+
self.socket.send(data);
|
859
|
+
}, 0);
|
860
|
+
return true; // only a reflection of fact that WS thinks it is open - could get returned before some lower-level failure.
|
796
861
|
} else {
|
797
862
|
return false;
|
798
863
|
}
|
@@ -823,185 +888,151 @@ Example:
|
|
823
888
|
this.Pusher.Connection = Connection;
|
824
889
|
}).call(this);
|
825
890
|
|
826
|
-
|
827
|
-
|
828
|
-
};
|
891
|
+
;(function() {
|
892
|
+
Pusher.Channels = function() {
|
893
|
+
this.channels = {};
|
894
|
+
};
|
829
895
|
|
830
|
-
Pusher.Channels.prototype = {
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
896
|
+
Pusher.Channels.prototype = {
|
897
|
+
add: function(channel_name, pusher) {
|
898
|
+
var existing_channel = this.find(channel_name);
|
899
|
+
if (!existing_channel) {
|
900
|
+
var channel = Pusher.Channel.factory(channel_name, pusher);
|
901
|
+
this.channels[channel_name] = channel;
|
902
|
+
return channel;
|
903
|
+
} else {
|
904
|
+
return existing_channel;
|
905
|
+
}
|
906
|
+
},
|
841
907
|
|
842
|
-
|
843
|
-
|
844
|
-
|
908
|
+
find: function(channel_name) {
|
909
|
+
return this.channels[channel_name];
|
910
|
+
},
|
845
911
|
|
846
|
-
|
847
|
-
|
848
|
-
|
912
|
+
remove: function(channel_name) {
|
913
|
+
delete this.channels[channel_name];
|
914
|
+
},
|
849
915
|
|
850
|
-
|
851
|
-
|
852
|
-
|
916
|
+
disconnect: function () {
|
917
|
+
for(var channel_name in this.channels){
|
918
|
+
this.channels[channel_name].disconnect()
|
919
|
+
}
|
853
920
|
}
|
854
|
-
}
|
855
|
-
};
|
856
|
-
|
857
|
-
Pusher.Channel = function(channel_name, pusher) {
|
858
|
-
var self = this;
|
859
|
-
Pusher.EventsDispatcher.call(this, function(event_name, event_data) {
|
860
|
-
Pusher.debug('No callbacks on ' + channel_name + ' for ' + event_name);
|
861
|
-
});
|
862
|
-
|
863
|
-
this.pusher = pusher;
|
864
|
-
this.name = channel_name;
|
865
|
-
this.subscribed = false;
|
866
|
-
|
867
|
-
this.bind('pusher_internal:subscription_succeeded', function(data) {
|
868
|
-
self.onSubscriptionSucceeded(data);
|
869
|
-
});
|
870
|
-
};
|
871
|
-
|
872
|
-
Pusher.Channel.prototype = {
|
873
|
-
// inheritable constructor
|
874
|
-
init: function() {},
|
875
|
-
disconnect: function() {},
|
876
|
-
|
877
|
-
onSubscriptionSucceeded: function(data) {
|
878
|
-
this.subscribed = true;
|
879
|
-
this.emit('pusher:subscription_succeeded');
|
880
|
-
},
|
881
|
-
|
882
|
-
authorize: function(pusher, callback){
|
883
|
-
callback(false, {}); // normal channels don't require auth
|
884
|
-
},
|
885
|
-
|
886
|
-
trigger: function(event, data) {
|
887
|
-
return this.pusher.send_event(event, data, this.name);
|
888
|
-
}
|
889
|
-
};
|
921
|
+
};
|
890
922
|
|
891
|
-
Pusher.
|
923
|
+
Pusher.Channel = function(channel_name, pusher) {
|
924
|
+
var self = this;
|
925
|
+
Pusher.EventsDispatcher.call(this, function(event_name, event_data) {
|
926
|
+
Pusher.debug('No callbacks on ' + channel_name + ' for ' + event_name);
|
927
|
+
});
|
892
928
|
|
929
|
+
this.pusher = pusher;
|
930
|
+
this.name = channel_name;
|
931
|
+
this.subscribed = false;
|
893
932
|
|
933
|
+
this.bind('pusher_internal:subscription_succeeded', function(data) {
|
934
|
+
self.onSubscriptionSucceeded(data);
|
935
|
+
});
|
936
|
+
};
|
894
937
|
|
895
|
-
Pusher.
|
938
|
+
Pusher.Channel.prototype = {
|
939
|
+
// inheritable constructor
|
940
|
+
init: function() {},
|
941
|
+
disconnect: function() {
|
942
|
+
this.subscribed = false;
|
943
|
+
this.emit("pusher_internal:disconnected");
|
944
|
+
},
|
896
945
|
|
897
|
-
|
898
|
-
|
899
|
-
|
946
|
+
onSubscriptionSucceeded: function(data) {
|
947
|
+
this.subscribed = true;
|
948
|
+
this.emit('pusher:subscription_succeeded');
|
949
|
+
},
|
900
950
|
|
901
|
-
|
902
|
-
|
903
|
-
}
|
904
|
-
xhr = (window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
|
905
|
-
}
|
951
|
+
authorize: function(socketId, options, callback){
|
952
|
+
return callback(false, {}); // normal channels don't require auth
|
953
|
+
},
|
906
954
|
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
if (xhr.status == 200) {
|
912
|
-
var data, parsed = false;
|
955
|
+
trigger: function(event, data) {
|
956
|
+
return this.pusher.send_event(event, data, this.name);
|
957
|
+
}
|
958
|
+
};
|
913
959
|
|
914
|
-
|
915
|
-
data = JSON.parse(xhr.responseText);
|
916
|
-
parsed = true;
|
917
|
-
} catch (e) {
|
918
|
-
callback(true, 'JSON returned from webapp was invalid, yet status code was 200. Data was: ' + xhr.responseText);
|
919
|
-
}
|
960
|
+
Pusher.Util.extend(Pusher.Channel.prototype, Pusher.EventsDispatcher.prototype);
|
920
961
|
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
962
|
+
Pusher.Channel.PrivateChannel = {
|
963
|
+
authorize: function(socketId, options, callback){
|
964
|
+
var self = this;
|
965
|
+
var authorizer = new Pusher.Channel.Authorizer(this, Pusher.channel_auth_transport, options);
|
966
|
+
return authorizer.authorize(socketId, function(err, authData) {
|
967
|
+
if(!err) {
|
968
|
+
self.emit('pusher_internal:authorized', authData);
|
927
969
|
}
|
928
|
-
}
|
929
|
-
};
|
930
|
-
xhr.send('socket_id=' + encodeURIComponent(pusher.connection.socket_id) + '&channel_name=' + encodeURIComponent(self.name));
|
931
|
-
},
|
932
|
-
jsonp: function(pusher, callback){
|
933
|
-
var qstring = 'socket_id=' + encodeURIComponent(pusher.connection.socket_id) + '&channel_name=' + encodeURIComponent(this.name);
|
934
|
-
var script = document.createElement("script");
|
935
|
-
// Hacked wrapper.
|
936
|
-
Pusher.auth_callbacks[this.name] = function(data) {
|
937
|
-
callback(false, data);
|
938
|
-
};
|
939
|
-
var callback_name = "Pusher.auth_callbacks['" + this.name + "']";
|
940
|
-
script.src = Pusher.channel_auth_endpoint+'?callback='+encodeURIComponent(callback_name)+'&'+qstring;
|
941
|
-
var head = document.getElementsByTagName("head")[0] || document.documentElement;
|
942
|
-
head.insertBefore( script, head.firstChild );
|
943
|
-
}
|
944
|
-
};
|
945
970
|
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
}
|
950
|
-
};
|
951
|
-
|
952
|
-
Pusher.Channel.PresenceChannel = {
|
953
|
-
init: function(){
|
954
|
-
this.bind('pusher_internal:member_added', function(data){
|
955
|
-
var member = this.members.add(data.user_id, data.user_info);
|
956
|
-
this.emit('pusher:member_added', member);
|
957
|
-
}.scopedTo(this))
|
958
|
-
|
959
|
-
this.bind('pusher_internal:member_removed', function(data){
|
960
|
-
var member = this.members.remove(data.user_id);
|
961
|
-
if (member) {
|
962
|
-
this.emit('pusher:member_removed', member);
|
963
|
-
}
|
964
|
-
}.scopedTo(this))
|
965
|
-
},
|
971
|
+
callback(err, authData);
|
972
|
+
});
|
973
|
+
}
|
974
|
+
};
|
966
975
|
|
967
|
-
|
968
|
-
|
969
|
-
|
976
|
+
Pusher.Channel.PresenceChannel = {
|
977
|
+
init: function(){
|
978
|
+
this.members = new Members(this); // leeches off channel events
|
979
|
+
},
|
970
980
|
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
981
|
+
onSubscriptionSucceeded: function(data) {
|
982
|
+
this.subscribed = true;
|
983
|
+
// We override this because we want the Members obj to be responsible for
|
984
|
+
// emitting the pusher:subscription_succeeded. It will do this after it has done its work.
|
985
|
+
}
|
986
|
+
};
|
975
987
|
|
976
|
-
|
977
|
-
|
988
|
+
var Members = function(channel) {
|
989
|
+
var self = this;
|
978
990
|
|
979
|
-
|
980
|
-
|
981
|
-
|
991
|
+
var reset = function() {
|
992
|
+
this._members_map = {};
|
993
|
+
this.count = 0;
|
994
|
+
this.me = null;
|
995
|
+
};
|
996
|
+
reset.call(this);
|
997
|
+
|
998
|
+
channel.bind('pusher_internal:authorized', function(authorizedData) {
|
999
|
+
var channelData = JSON.parse(authorizedData.channel_data);
|
1000
|
+
channel.bind("pusher_internal:subscription_succeeded", function(subscriptionData) {
|
1001
|
+
self._members_map = subscriptionData.presence.hash;
|
1002
|
+
self.count = subscriptionData.presence.count;
|
1003
|
+
self.me = self.get(channelData.user_id);
|
1004
|
+
channel.emit('pusher:subscription_succeeded', self);
|
1005
|
+
});
|
1006
|
+
});
|
982
1007
|
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
id: i,
|
987
|
-
info: this._members_map[i]
|
988
|
-
});
|
1008
|
+
channel.bind('pusher_internal:member_added', function(data) {
|
1009
|
+
if(self.get(data.user_id) === null) { // only incr if user_id does not already exist
|
1010
|
+
self.count++;
|
989
1011
|
}
|
990
|
-
},
|
991
1012
|
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
return this.get(id);
|
996
|
-
},
|
1013
|
+
self._members_map[data.user_id] = data.user_info;
|
1014
|
+
channel.emit('pusher:member_added', self.get(data.user_id));
|
1015
|
+
});
|
997
1016
|
|
998
|
-
|
999
|
-
var member =
|
1000
|
-
if
|
1001
|
-
delete
|
1002
|
-
|
1017
|
+
channel.bind('pusher_internal:member_removed', function(data) {
|
1018
|
+
var member = self.get(data.user_id);
|
1019
|
+
if(member) {
|
1020
|
+
delete self._members_map[data.user_id];
|
1021
|
+
self.count--;
|
1022
|
+
channel.emit('pusher:member_removed', member);
|
1023
|
+
}
|
1024
|
+
});
|
1025
|
+
|
1026
|
+
channel.bind('pusher_internal:disconnected', function() {
|
1027
|
+
reset.call(self);
|
1028
|
+
});
|
1029
|
+
};
|
1030
|
+
|
1031
|
+
Members.prototype = {
|
1032
|
+
each: function(callback) {
|
1033
|
+
for(var i in this._members_map) {
|
1034
|
+
callback(this.get(i));
|
1003
1035
|
}
|
1004
|
-
return member;
|
1005
1036
|
},
|
1006
1037
|
|
1007
1038
|
get: function(user_id) {
|
@@ -1013,27 +1044,114 @@ Pusher.Channel.PresenceChannel = {
|
|
1013
1044
|
} else { // have never heard of this user
|
1014
1045
|
return null;
|
1015
1046
|
}
|
1047
|
+
}
|
1048
|
+
};
|
1049
|
+
|
1050
|
+
Pusher.Channel.factory = function(channel_name, pusher){
|
1051
|
+
var channel = new Pusher.Channel(channel_name, pusher);
|
1052
|
+
if (channel_name.indexOf('private-') === 0) {
|
1053
|
+
Pusher.Util.extend(channel, Pusher.Channel.PrivateChannel);
|
1054
|
+
} else if (channel_name.indexOf('presence-') === 0) {
|
1055
|
+
Pusher.Util.extend(channel, Pusher.Channel.PrivateChannel);
|
1056
|
+
Pusher.Util.extend(channel, Pusher.Channel.PresenceChannel);
|
1057
|
+
};
|
1058
|
+
channel.init();
|
1059
|
+
return channel;
|
1060
|
+
};
|
1061
|
+
}).call(this);
|
1062
|
+
;(function() {
|
1063
|
+
Pusher.Channel.Authorizer = function(channel, type, options) {
|
1064
|
+
this.channel = channel;
|
1065
|
+
this.type = type;
|
1066
|
+
|
1067
|
+
this.authOptions = (options || {}).auth || {};
|
1068
|
+
};
|
1069
|
+
|
1070
|
+
Pusher.Channel.Authorizer.prototype = {
|
1071
|
+
composeQuery: function(socketId) {
|
1072
|
+
var query = '&socket_id=' + encodeURIComponent(socketId)
|
1073
|
+
+ '&channel_name=' + encodeURIComponent(this.channel.name);
|
1074
|
+
|
1075
|
+
for(var i in this.authOptions.params) {
|
1076
|
+
query += "&" + encodeURIComponent(i) + "=" + encodeURIComponent(this.authOptions.params[i]);
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
return query;
|
1016
1080
|
},
|
1017
1081
|
|
1018
|
-
|
1019
|
-
this.
|
1020
|
-
this.count = 0;
|
1082
|
+
authorize: function(socketId, callback) {
|
1083
|
+
return Pusher.authorizers[this.type].call(this, socketId, callback);
|
1021
1084
|
}
|
1022
|
-
}
|
1023
|
-
};
|
1024
|
-
|
1025
|
-
Pusher.Channel.factory = function(channel_name, pusher){
|
1026
|
-
var channel = new Pusher.Channel(channel_name, pusher);
|
1027
|
-
if (channel_name.indexOf('private-') === 0) {
|
1028
|
-
Pusher.Util.extend(channel, Pusher.Channel.PrivateChannel);
|
1029
|
-
} else if (channel_name.indexOf('presence-') === 0) {
|
1030
|
-
Pusher.Util.extend(channel, Pusher.Channel.PrivateChannel);
|
1031
|
-
Pusher.Util.extend(channel, Pusher.Channel.PresenceChannel);
|
1032
1085
|
};
|
1033
|
-
channel.init();
|
1034
|
-
return channel;
|
1035
|
-
};
|
1036
1086
|
|
1087
|
+
|
1088
|
+
Pusher.auth_callbacks = {};
|
1089
|
+
Pusher.authorizers = {
|
1090
|
+
ajax: function(socketId, callback){
|
1091
|
+
var self = this, xhr;
|
1092
|
+
|
1093
|
+
if (Pusher.XHR) {
|
1094
|
+
xhr = new Pusher.XHR();
|
1095
|
+
} else {
|
1096
|
+
xhr = (window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
xhr.open("POST", Pusher.channel_auth_endpoint, true);
|
1100
|
+
|
1101
|
+
// add request headers
|
1102
|
+
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
|
1103
|
+
for(var headerName in this.authOptions.headers) {
|
1104
|
+
xhr.setRequestHeader(headerName, this.authOptions.headers[headerName]);
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
xhr.onreadystatechange = function() {
|
1108
|
+
if (xhr.readyState == 4) {
|
1109
|
+
if (xhr.status == 200) {
|
1110
|
+
var data, parsed = false;
|
1111
|
+
|
1112
|
+
try {
|
1113
|
+
data = JSON.parse(xhr.responseText);
|
1114
|
+
parsed = true;
|
1115
|
+
} catch (e) {
|
1116
|
+
callback(true, 'JSON returned from webapp was invalid, yet status code was 200. Data was: ' + xhr.responseText);
|
1117
|
+
}
|
1118
|
+
|
1119
|
+
if (parsed) { // prevents double execution.
|
1120
|
+
callback(false, data);
|
1121
|
+
}
|
1122
|
+
} else {
|
1123
|
+
Pusher.warn("Couldn't get auth info from your webapp", xhr.status);
|
1124
|
+
callback(true, xhr.status);
|
1125
|
+
}
|
1126
|
+
}
|
1127
|
+
};
|
1128
|
+
|
1129
|
+
xhr.send(this.composeQuery(socketId));
|
1130
|
+
return xhr;
|
1131
|
+
},
|
1132
|
+
|
1133
|
+
jsonp: function(socketId, callback){
|
1134
|
+
if(this.authOptions.headers !== undefined) {
|
1135
|
+
Pusher.warn("Warn", "To send headers with the auth request, you must use AJAX, rather than JSONP.");
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
var script = document.createElement("script");
|
1139
|
+
// Hacked wrapper.
|
1140
|
+
Pusher.auth_callbacks[this.channel.name] = function(data) {
|
1141
|
+
callback(false, data);
|
1142
|
+
};
|
1143
|
+
|
1144
|
+
var callback_name = "Pusher.auth_callbacks['" + this.channel.name + "']";
|
1145
|
+
script.src = Pusher.channel_auth_endpoint
|
1146
|
+
+ '?callback='
|
1147
|
+
+ encodeURIComponent(callback_name)
|
1148
|
+
+ this.composeQuery(socketId);
|
1149
|
+
|
1150
|
+
var head = document.getElementsByTagName("head")[0] || document.documentElement;
|
1151
|
+
head.insertBefore( script, head.firstChild );
|
1152
|
+
}
|
1153
|
+
};
|
1154
|
+
}).call(this);
|
1037
1155
|
var _require = (function () {
|
1038
1156
|
|
1039
1157
|
var handleScriptLoaded;
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pusher_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,19 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pusher
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.9.
|
21
|
+
version: 0.9.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.2
|
25
30
|
description: Adds pusher.js/backpusher.js to the asset pipeline and pusher-gem to
|
26
31
|
to your app.
|
27
32
|
email:
|
@@ -57,7 +62,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
62
|
version: '0'
|
58
63
|
requirements: []
|
59
64
|
rubyforge_project:
|
60
|
-
rubygems_version: 1.8.
|
65
|
+
rubygems_version: 1.8.21
|
61
66
|
signing_key:
|
62
67
|
specification_version: 3
|
63
68
|
summary: Pusher integration for Rails 3.1+
|