Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Remove trailing whitespace.

  • Loading branch information...
commit 59e520558fb798b0769b7aef796f1ea6d8619d2c 1 parent 4d5d7af
@jcoglan jcoglan authored
Showing with 2,155 additions and 2,155 deletions.
  1. +2 −2 examples/automate.rb
  2. +6 −6 examples/node/benchmark.js
  3. +2 −2 examples/node/client.js
  4. +3 −3 examples/node/server.js
  5. +6 −6 examples/ruby/benchmark.rb
  6. +4 −4 examples/ruby/client.rb
  7. +3 −3 examples/ruby/cluster.rb
  8. +3 −3 examples/ruby/pingpong.rb
  9. +1 −1  examples/ruby/server.rb
  10. +8 −8 examples/shared/public/index.html
  11. +14 −14 examples/shared/public/soapbox.js
  12. +50 −50 javascript/adapters/node_adapter.js
  13. +9 −9 javascript/adapters/static_server.js
  14. +8 −8 javascript/engines/connection.js
  15. +19 −19 javascript/engines/memory.js
  16. +18 −18 javascript/engines/proxy.js
  17. +2 −2 javascript/error.js
  18. +20 −20 javascript/faye.js
  19. +8 −8 javascript/mixins/deferrable.js
  20. +7 −7 javascript/mixins/logging.js
  21. +8 −8 javascript/mixins/publisher.js
  22. +1 −1  javascript/mixins/timeouts.js
  23. +22 −22 javascript/protocol/channel.js
  24. +68 −68 javascript/protocol/client.js
  25. +5 −5 javascript/protocol/extensible.js
  26. +5 −5 javascript/protocol/grammar.js
  27. +57 −57 javascript/protocol/server.js
  28. +2 −2 javascript/protocol/socket.js
  29. +2 −2 javascript/protocol/subscription.js
  30. +9 −9 javascript/transport/cors.js
  31. +11 −11 javascript/transport/event_source.js
  32. +7 −7 javascript/transport/jsonp.js
  33. +10 −10 javascript/transport/node_http.js
  34. +1 −1  javascript/transport/node_local.js
  35. +15 −15 javascript/transport/transport.js
  36. +18 −18 javascript/transport/web_socket.js
  37. +10 −10 javascript/transport/xhr.js
  38. +7 −7 javascript/util/browser/event.js
  39. +11 −11 javascript/util/browser/uri.js
  40. +4 −4 javascript/util/class.js
  41. +3 −3 javascript/util/namespace.js
  42. +6 −6 javascript/util/set.js
  43. +20 −20 lib/faye.rb
  44. +43 −43 lib/faye/adapters/rack_adapter.rb
  45. +11 −11 lib/faye/adapters/static_server.rb
  46. +13 −13 lib/faye/engines/connection.rb
  47. +21 −21 lib/faye/engines/memory.rb
  48. +23 −23 lib/faye/engines/proxy.rb
  49. +6 −6 lib/faye/error.rb
  50. +12 −12 lib/faye/mixins/logging.rb
  51. +6 −6 lib/faye/mixins/publisher.rb
  52. +1 −1  lib/faye/mixins/timeouts.rb
  53. +24 −24 lib/faye/protocol/channel.rb
  54. +68 −68 lib/faye/protocol/client.rb
  55. +7 −7 lib/faye/protocol/extensible.rb
  56. +13 −13 lib/faye/protocol/grammar.rb
  57. +57 −57 lib/faye/protocol/server.rb
  58. +4 −4 lib/faye/protocol/socket.rb
  59. +4 −4 lib/faye/protocol/subscription.rb
  60. +13 −13 lib/faye/transport/http.rb
  61. +5 −5 lib/faye/transport/local.rb
  62. +19 −19 lib/faye/transport/transport.rb
  63. +20 −20 lib/faye/transport/web_socket.rb
  64. +4 −4 lib/faye/util/namespace.rb
  65. +2 −2 site/src/layouts/application.haml
  66. +31 −31 site/src/pages/architecture.haml
  67. +31 −31 site/src/pages/browser.haml
  68. +7 −7 site/src/pages/browser/extensions.haml
  69. +9 −9 site/src/pages/browser/publishing.haml
  70. +14 −14 site/src/pages/browser/subscribing.haml
  71. +7 −7 site/src/pages/browser/transport.haml
  72. +14 −14 site/src/pages/download.haml
  73. +9 −9 site/src/pages/index.haml
  74. +13 −13 site/src/pages/node.haml
  75. +7 −7 site/src/pages/node/clients.haml
  76. +46 −46 site/src/pages/node/engines.haml
  77. +25 −25 site/src/pages/node/extensions.haml
  78. +17 −17 site/src/pages/node/monitoring.haml
  79. +3 −3 site/src/pages/node/websockets.haml
  80. +17 −17 site/src/pages/ruby.haml
  81. +13 −13 site/src/pages/ruby/clients.haml
  82. +45 −45 site/src/pages/ruby/engines.haml
  83. +24 −24 site/src/pages/ruby/extensions.haml
  84. +17 −17 site/src/pages/ruby/monitoring.haml
  85. +3 −3 site/src/pages/ruby/websockets.haml
  86. +88 −88 site/src/pages/security.haml
  87. +3 −3 site/src/partials/browser_navigation.haml
  88. +3 −3 site/src/partials/node_navigation.haml
  89. +4 −4 site/src/partials/ruby_navigation.haml
  90. +19 −19 site/src/stylesheets/main.sass
  91. +5 −5 spec/browser.html
  92. +3 −3 spec/javascript/channel_spec.js
  93. +87 −87 spec/javascript/client_spec.js
  94. +1 −1  spec/javascript/engine/memory_spec.js
  95. +70 −70 spec/javascript/engine_spec.js
  96. +6 −6 spec/javascript/faye_spec.js
  97. +12 −12 spec/javascript/grammar_spec.js
  98. +46 −46 spec/javascript/node_adapter_spec.js
  99. +4 −4 spec/javascript/publisher_spec.js
  100. +21 −21 spec/javascript/server/connect_spec.js
  101. +15 −15 spec/javascript/server/disconnect_spec.js
  102. +6 −6 spec/javascript/server/extensions_spec.js
  103. +18 −18 spec/javascript/server/handshake_spec.js
  104. +23 −23 spec/javascript/server/integration_spec.js
  105. +9 −9 spec/javascript/server/publish_spec.js
  106. +30 −30 spec/javascript/server/subscribe_spec.js
  107. +30 −30 spec/javascript/server/unsubscribe_spec.js
  108. +15 −15 spec/javascript/server_spec.js
  109. +19 −19 spec/javascript/transport_spec.js
  110. +2 −2 spec/node.js
  111. +2 −2 spec/ruby/channel_spec.rb
  112. +82 −82 spec/ruby/client_spec.rb
  113. +51 −51 spec/ruby/engine_examples.rb
  114. +5 −5 spec/ruby/faye_spec.rb
  115. +12 −12 spec/ruby/grammar_spec.rb
  116. +4 −4 spec/ruby/publisher_spec.rb
  117. +34 −34 spec/ruby/rack_adapter_spec.rb
  118. +22 −22 spec/ruby/server/connect_spec.rb
  119. +16 −16 spec/ruby/server/disconnect_spec.rb
  120. +8 −8 spec/ruby/server/extensions_spec.rb
  121. +19 −19 spec/ruby/server/handshake_spec.rb
  122. +22 −22 spec/ruby/server/integration_spec.rb
  123. +9 −9 spec/ruby/server/publish_spec.rb
  124. +31 −31 spec/ruby/server/subscribe_spec.rb
  125. +31 −31 spec/ruby/server/unsubscribe_spec.rb
  126. +17 −17 spec/ruby/server_spec.rb
  127. +22 −22 spec/ruby/transport_spec.rb
  128. +1 −1  spec/testswarm
  129. +5 −5 spec/thin_proxy.rb
View
4 examples/automate.rb
@@ -48,11 +48,11 @@
BROWSERS.each do |name, sender|
BROWSERS.each do |at, target|
next if at == name
-
+
Terminus.browser = sender
fill_in 'message', :with => "@#{at} Hello, world!"
click_button 'Send'
-
+
Terminus.browser = target
unless page.has_content?("#{name}: @#{at} Hello, world!")
Terminus.return_to_dock
View
12 examples/node/benchmark.js
@@ -1,5 +1,5 @@
var faye = require('../../build/node/faye-node'),
-
+
port = process.argv[2] || 8000,
path = process.argv[3] || 'bayeux',
scheme = process.argv[4] === 'ssl' ? 'https' : 'http';
@@ -9,25 +9,25 @@ var A = new faye.Client(scheme + '://localhost:' + port + '/' + path),
A.connect(function() {
B.connect(function() {
-
+
var time = new Date().getTime(),
MAX = 1000;
-
+
var stop = function() {
console.log(new Date().getTime() - time);
process.exit();
};
-
+
var handle = function(client, channel) {
return function(n) {
if (n === MAX) return stop();
client.publish(channel, n + 1);
};
};
-
+
var subA = A.subscribe('/chat/a', handle(A, '/chat/b')),
subB = B.subscribe('/chat/b', handle(B, '/chat/a'));
-
+
subA.callback(function() {
subB.callback(function() {
console.log('START');
View
4 examples/node/client.js
@@ -8,7 +8,7 @@
// connected users.
var faye = require('../../build/node/faye-node'),
-
+
port = process.argv[2] || 8000,
path = process.argv[3] || 'bayeux',
scheme = process.argv[4] === 'ssl' ? 'https' : 'http',
@@ -19,7 +19,7 @@ var client = new faye.Client(endpoint);
var subscription = client.subscribe('/chat/*', function(message) {
var user = message.user;
-
+
var publication = client.publish('/members/' + user, {
user: 'node-logger',
message: ' Got your message, ' + user + '!'
View
6 examples/node/server.js
@@ -8,11 +8,11 @@ var fs = require('fs'),
var SHARED_DIR = path.dirname(__filename) + '/../shared',
PUBLIC_DIR = SHARED_DIR + '/public',
-
+
bayeux = new faye.NodeAdapter({mount: '/bayeux', timeout: 20}),
port = process.argv[2] || '8000',
secure = process.argv[3] === 'ssl',
-
+
sslOpts = {
key: fs.readFileSync(SHARED_DIR + '/server.key'),
cert: fs.readFileSync(SHARED_DIR + '/server.crt')
@@ -20,7 +20,7 @@ var SHARED_DIR = path.dirname(__filename) + '/../shared',
var handleRequest = function(request, response) {
var path = (request.url === '/') ? '/index.html' : request.url;
-
+
fs.readFile(PUBLIC_DIR + path, function(err, content) {
var status = err ? 404 : 200;
response.writeHead(status, {'Content-Type': 'text/html'});
View
12 examples/ruby/benchmark.rb
@@ -8,18 +8,18 @@
EM.run {
A = Faye::Client.new("#{scheme}://localhost:#{port}/#{path}")
B = Faye::Client.new("#{scheme}://localhost:#{port}/#{path}")
-
+
A.connect do
B.connect do
-
+
time = Time.now.to_f * 1000
MAX = 1000
-
+
stop = lambda do
puts Time.now.to_f * 1000 - time
EM.stop
end
-
+
handle = lambda do |client, channel|
lambda do |n|
if n == MAX
@@ -29,10 +29,10 @@
end
end
end
-
+
sub_a = A.subscribe('/chat/a', &handle.call(A, '/chat/b'))
sub_b = B.subscribe('/chat/b', &handle.call(B, '/chat/a'))
-
+
sub_a.callback do
sub_b.callback do
puts 'START'
View
8 examples/ruby/client.rb
@@ -18,10 +18,10 @@
EM.run {
puts "Connecting to #{endpoint}"
client = Faye::Client.new(endpoint)
-
+
subscription = client.subscribe '/chat/*' do |message|
user = message['user']
-
+
publication = client.publish("/members/#{ user }", {
"user" => "ruby-logger",
"message" => "Got your message, #{ user }!"
@@ -33,14 +33,14 @@
puts "[PUBLISH FAILED] #{error.inspect}"
end
end
-
+
subscription.callback do
puts "[SUBSCRIBE SUCCEEDED]"
end
subscription.errback do |error|
puts "[SUBSCRIBE FAILED] #{error.inspect}"
end
-
+
client.bind 'transport:down' do
puts "[CONNECTION DOWN]"
end
View
6 examples/ruby/cluster.rb
@@ -13,15 +13,15 @@
server = servers[:ruby]
client_a = Faye::Client.new("http://localhost:#{server[:ports][0]}/#{server[:path]}")
client_b = Faye::Client.new("http://localhost:#{server[:ports][1]}/#{server[:path]}")
-
+
time = nil
-
+
sub = client_a.subscribe '/chat/foo' do |message|
puts Time.now.to_f * 1000 - time
puts message['text']
EM.stop
end
-
+
sub.callback do
client_b.connect do
time = Time.now.to_f * 1000
View
6 examples/ruby/pingpong.rb
@@ -4,19 +4,19 @@
EM.run {
ENDPOINT = 'http://localhost:9292/bayeux'
puts 'Connecting to ' + ENDPOINT
-
+
ping = Faye::Client.new(ENDPOINT)
ping.subscribe('/ping') do
puts 'PING'
EM.add_timer(1) { ping.publish('/pong', {}) }
end
-
+
pong = Faye::Client.new(ENDPOINT)
pong.subscribe('/pong') do
puts 'PONG'
EM.add_timer(1) { ping.publish('/ping', {}) }
end
-
+
EM.add_timer(0.5) { ping.publish('/pong', {}) }
}
View
2  examples/ruby/server.rb
@@ -30,7 +30,7 @@ def response(env)
EM.run {
thin = Rack::Handler.get('thin')
thin.run(App, :Port => port) do |s|
-
+
if secure
s.ssl = true
s.ssl_options = {
View
16 examples/shared/public/index.html
@@ -12,40 +12,40 @@
</head>
<body>
<div class="container">
-
+
<h1><em>Soapbox</em> | a Twitter-style chat app</h1>
-
+
<form id="enterUsername">
<label for="username">Pick a username</label>
<input type="text" name="username" id="username">
<input type="submit" value="Go">
</form>
-
+
<div id="app">
<form id="addFollowee">
<label for="followee">Follow</label>
<input type="text" name="followee" id="followee">
<input type="submit" value="Follow">
</form>
-
+
<form id="postMessage">
<label for="message">Post a message</label><br>
<textarea name="message" id="message" rows="3" cols="40"></textarea>
<input type="submit" value="Send">
</form>
-
+
<ul id="stream">
</ul>
</div>
-
+
<script type="text/javascript">
Faye.Logging.logLevel = 'debug';
-
+
var scheme = window.location.protocol,
host = location.hostname,
port = location.port,
path = '/bayeux';
-
+
Bayeux = new Faye.Client(scheme + '//' + host + (port ? ':' + port : '') + path);
Soapbox.init(Bayeux);
</script>
View
28 examples/shared/public/soapbox.js
@@ -7,15 +7,15 @@ Soapbox = {
init: function(bayeux) {
var self = this;
this._bayeux = bayeux;
-
+
this._login = $('#enterUsername');
this._app = $('#app');
this._follow = $('#addFollowee');
this._post = $('#postMessage');
this._stream = $('#stream');
-
+
this._app.hide();
-
+
// When the user enters a username, store it and start the app
this._login.submit(function() {
self._username = $('#username').val();
@@ -23,7 +23,7 @@ Soapbox = {
return false;
});
},
-
+
/**
* Starts the application after a username has been entered. A subscription is
* made to receive messages that mention this user, and forms are set up to
@@ -32,23 +32,23 @@ Soapbox = {
launch: function() {
var self = this;
this._bayeux.subscribe('/members/' + this._username, this.accept, this);
-
+
// Hide login form, show main application UI
this._login.fadeOut('slow', function() {
self._app.fadeIn('slow');
});
-
+
// When we add a follower, subscribe to a channel to which the followed user
// will publish messages
this._follow.submit(function() {
var follow = $('#followee'),
name = follow.val();
-
+
self._bayeux.subscribe('/chat/' + name, self.accept, self);
follow.val('');
return false;
});
-
+
// When we enter a message, send it and clear the message field.
this._post.submit(function() {
var msg = $('#message');
@@ -56,7 +56,7 @@ Soapbox = {
msg.val('');
return false;
});
-
+
// Detect network problems and disable the form when offline
this._bayeux.bind('transport:down', function() {
this._post.find('textarea,input').attr('disabled', true);
@@ -65,7 +65,7 @@ Soapbox = {
this._post.find('textarea,input').attr('disabled', false);
}, this);
},
-
+
/**
* Sends messages that the user has entered. The message is scanned for
* @reply-style mentions of other users, and the message is sent to those
@@ -76,17 +76,17 @@ Soapbox = {
words = message.split(/\s+/),
self = this,
pattern = /\@[a-z0-9]+/i;
-
+
// Extract @replies from the message
$.each(words, function(i, word) {
if (!pattern.test(word)) return;
word = word.replace(/[^a-z0-9]/ig, '');
if (word !== self._username) mentions.push(word);
});
-
+
// Message object to transmit over Bayeux channels
message = {user: this._username, message: message};
-
+
// Publish to this user's 'from' channel, and to channels for any @replies
// found in the message
this._bayeux.publish('/chat/' + this._username, message);
@@ -94,7 +94,7 @@ Soapbox = {
self._bayeux.publish('/members/' + name, message);
});
},
-
+
/**
* Handler for messages received over subscribed channels. Takes the message
* object sent by the post() method and displays it in the user's message list.
View
100 javascript/adapters/node_adapter.js
@@ -24,54 +24,54 @@ Faye.withDataFor = function(transport, callback, context) {
Faye.NodeAdapter = Faye.Class({
DEFAULT_ENDPOINT: '<%= Faye::RackAdapter::DEFAULT_ENDPOINT %>',
SCRIPT_PATH: 'faye-browser-min.js',
-
+
// https://github.com/joyent/node/issues/2727
CIPHER_ORDER: 'ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM',
CIPHER_OPTIONS: require('constants').SSL_OP_CIPHER_SERVER_PREFERENCE,
-
+
TYPE_JSON: {'Content-Type': 'application/json; charset=utf-8'},
TYPE_SCRIPT: {'Content-Type': 'text/javascript; charset=utf-8'},
TYPE_TEXT: {'Content-Type': 'text/plain; charset=utf-8'},
-
-
+
+
initialize: function(options) {
this._options = options || {};
this._endpoint = this._options.mount || this.DEFAULT_ENDPOINT;
this._endpointRe = new RegExp('^' + this._endpoint + '(/[^/]+)*(\\.[^\\.]+)?$');
this._server = new Faye.Server(this._options);
-
+
this._static = new Faye.StaticServer(path.dirname(__filename) + '/../browser', /\.(?:js|map)$/);
this._static.map(path.basename(this._endpoint) + '.js', this.SCRIPT_PATH);
this._static.map('client.js', this.SCRIPT_PATH);
-
+
var extensions = this._options.extensions;
if (!extensions) return;
-
+
extensions = [].concat(extensions);
for (var i = 0, n = extensions.length; i < n; i++)
this.addExtension(extensions[i]);
},
-
+
addExtension: function(extension) {
return this._server.addExtension(extension);
},
-
+
removeExtension: function(extension) {
return this._server.removeExtension(extension);
},
-
+
bind: function() {
return this._server._engine.bind.apply(this._server._engine, arguments);
},
-
+
unbind: function() {
return this._server._engine.unbind.apply(this._server._engine, arguments);
},
-
+
getClient: function() {
return this._client = this._client || new Faye.Client(this._server);
},
-
+
listen: function(port, sslOptions, callback, context) {
var ssl = sslOptions && sslOptions.cert
? { key: fs.readFileSync(sslOptions.key),
@@ -80,98 +80,98 @@ Faye.NodeAdapter = Faye.Class({
secureOptions: this.CIPHER_OPTIONS
}
: null;
-
+
if (ssl && sslOptions.ca)
ssl.ca = Faye.map(sslOptions.ca, function(ca) { return fs.readFileSync(ca) });
-
+
var httpServer = ssl
? https.createServer(ssl, function() {})
: http.createServer(function() {});
-
+
this.attach(httpServer);
httpServer.listen(port, function() {
if (callback) callback.call(context);
});
this._httpServer = httpServer;
},
-
+
stop: function(callback, context) {
this._httpServer.addListener('close', function() {
if (callback) callback.call(context);
});
this._httpServer.close();
},
-
+
attach: function(httpServer) {
this._overrideListeners(httpServer, 'request', 'handle');
this._overrideListeners(httpServer, 'upgrade', 'handleUpgrade');
},
-
+
_overrideListeners: function(httpServer, event, method) {
var listeners = httpServer.listeners(event),
self = this;
-
+
httpServer.removeAllListeners(event);
-
+
httpServer.addListener(event, function(request) {
if (self.check(request)) return self[method].apply(self, arguments);
-
+
for (var i = 0, n = listeners.length; i < n; i++)
listeners[i].apply(this, arguments);
});
},
-
+
check: function(request) {
var path = url.parse(request.url, true).pathname;
return !!this._endpointRe.test(path);
},
-
+
handle: function(request, response) {
var requestUrl = url.parse(request.url, true),
requestMethod = request.method,
self = this;
-
+
if (this._static.test(requestUrl.pathname))
return this._static.call(request, response);
-
+
// http://groups.google.com/group/faye-users/browse_thread/thread/4a01bb7d25d3636a
if (requestMethod === 'OPTIONS' || request.headers['access-control-request-method'] === 'POST')
return this._handleOptions(request, response);
-
+
if (Faye.EventSource.isEventSource(request))
return this.handleEventSource(request, response);
-
+
if (requestMethod === 'GET')
return this._callWithParams(request, response, requestUrl.query);
-
+
if (requestMethod === 'POST')
return Faye.withDataFor(request, function(data) {
var type = (request.headers['content-type'] || '').split(';')[0],
params = (type === 'application/json')
? {message: data}
: querystring.parse(data);
-
+
request.body = data;
self._callWithParams(request, response, params);
});
-
+
this._returnError(response);
},
-
+
handleUpgrade: function(request, socket, head) {
var ws = new Faye.WebSocket(request, socket, head, null, {ping: this._options.ping}),
clientId = null,
self = this;
-
+
ws.onmessage = function(event) {
try {
self.debug('Received message via WebSocket[' + ws.version + ']: ?', event.data);
-
+
var message = JSON.parse(event.data);
clientId = Faye.clientIdFromMessages(message);
-
+
self._server.openSocket(clientId, ws);
-
+
self._server.process(message, false, function(replies) {
if (ws) ws.send(JSON.stringify(replies));
});
@@ -179,36 +179,36 @@ Faye.NodeAdapter = Faye.Class({
self.error(e.message + '\nBacktrace:\n' + e.stack);
}
};
-
+
ws.onclose = function(event) {
self._server.closeSocket(clientId);
ws = null;
};
},
-
+
handleEventSource: function(request, response) {
var es = new Faye.EventSource(request, response, {ping: this._options.ping}),
clientId = es.url.split('/').pop(),
self = this;
-
+
this.debug('Opened EventSource connection for ?', clientId);
this._server.openSocket(clientId, es);
-
+
es.onclose = function(event) {
self._server.closeSocket(clientId);
es = null;
};
},
-
+
_callWithParams: function(request, response, params) {
if (!params.message) {
this.error('Received request with no message: ?', this._formatRequest(request));
return this._returnError(response);
}
-
+
try {
this.debug('Received message via HTTP ' + request.method + ': ?', params.message);
-
+
var message = JSON.parse(params.message),
jsonp = params.jsonp || Faye.JSONP_CALLBACK,
isGet = (request.method === 'GET'),
@@ -217,16 +217,16 @@ Faye.NodeAdapter = Faye.Class({
origin = request.headers.origin;
if (isGet) this._server.flushConnection(message);
-
+
if (origin) headers['Access-Control-Allow-Origin'] = origin;
headers['Cache-Control'] = 'no-cache, no-store';
-
+
this._server.process(message, false, function(replies) {
var body = JSON.stringify(replies);
if (isGet) body = jsonp + '(' + body + ');';
headers['Content-Length'] = new Buffer(body, 'utf8').length.toString();
headers['Connection'] = 'close';
-
+
this.debug('HTTP response: ?', body);
response.writeHead(200, headers);
response.write(body);
@@ -237,11 +237,11 @@ Faye.NodeAdapter = Faye.Class({
this._returnError(response);
}
},
-
+
_formatRequest: function(request) {
var method = request.method.toUpperCase(),
string = 'curl -X ' + method;
-
+
string += " 'http://" + request.headers.host + request.url + "'";
if (method === 'POST') {
string += " -H 'Content-Type: " + request.headers['content-type'] + "'";
@@ -249,7 +249,7 @@ Faye.NodeAdapter = Faye.Class({
}
return string;
},
-
+
_handleOptions: function(request, response) {
var headers = {
'Access-Control-Allow-Origin': '*',
@@ -262,7 +262,7 @@ Faye.NodeAdapter = Faye.Class({
response.write('');
response.end();
},
-
+
_returnError: function(response) {
response.writeHead(400, this.TYPE_TEXT);
response.write('Bad request');
View
18 javascript/adapters/static_server.js
@@ -5,25 +5,25 @@ Faye.StaticServer = Faye.Class({
this._pathMap = {};
this._index = {};
},
-
+
map: function(requestPath, filename) {
this._pathMap[requestPath] = filename;
},
-
+
test: function(pathname) {
return this._pathRegex.test(pathname);
},
-
+
call: function(request, response) {
var pathname = url.parse(request.url, true).pathname;
pathname = path.basename(pathname);
pathname = this._pathMap[pathname] || pathname;
-
+
this._index[pathname] = this._index[pathname] || {};
-
+
var cache = this._index[pathname],
fullpath = path.join(this._directory, pathname);
-
+
try {
cache.content = cache.content || fs.readFileSync(fullpath);
cache.digest = cache.digest || crypto.createHash('sha1').update(cache.content).digest('hex');
@@ -32,15 +32,15 @@ Faye.StaticServer = Faye.Class({
response.writeHead(404, {});
return response.end();
}
-
+
var type = /\.js$/.test(pathname) ? 'TYPE_SCRIPT' : 'TYPE_JSON',
headers = Faye.extend({}, Faye.NodeAdapter.prototype[type]),
ims = request.headers['if-modified-since'];
-
+
headers['Content-Length'] = '0';
headers['ETag'] = cache.digest;
headers['Last-Modified'] = cache.mtime.toGMTString();
-
+
if (request.headers['if-none-match'] === cache.digest) {
response.writeHead(304, headers);
response.end();
View
16 javascript/engines/connection.js
@@ -5,41 +5,41 @@ Faye.Engine.Connection = Faye.Class({
this._options = options;
this._inbox = [];
},
-
+
deliver: function(message) {
if (this.socket) return this.socket.send(message);
this._inbox.push(message);
this._beginDeliveryTimeout();
},
-
+
connect: function(options, callback, context) {
options = options || {};
var timeout = (options.timeout !== undefined) ? options.timeout / 1000 : this._engine.timeout;
-
+
this.setDeferredStatus('deferred');
this.callback(callback, context);
-
+
this._beginDeliveryTimeout();
this._beginConnectionTimeout(timeout);
},
-
+
flush: function(force) {
this._releaseConnection(force);
this.setDeferredStatus('succeeded', this._inbox);
this._inbox = [];
},
-
+
_releaseConnection: function(force) {
if (force || !this.socket) this._engine.closeConnection(this._id);
this.removeTimeout('connection');
this.removeTimeout('delivery');
},
-
+
_beginDeliveryTimeout: function() {
if (this._inbox.length === 0) return;
this.addTimeout('delivery', this._engine.MAX_DELAY, this.flush, this);
},
-
+
_beginConnectionTimeout: function(timeout) {
this.addTimeout('connection', timeout, this.flush, this);
}
View
38 javascript/engines/memory.js
@@ -19,14 +19,14 @@ Faye.Engine.Memory.prototype = {
this._server.trigger('handshake', clientId);
callback.call(context, clientId);
},
-
+
destroyClient: function(clientId, callback, context) {
if (!this._namespace.exists(clientId)) return;
var clients = this._clients;
-
+
if (clients[clientId])
clients[clientId].forEach(function(channel) { this.unsubscribe(clientId, channel) }, this);
-
+
this.removeTimeout(clientId);
this._namespace.release(clientId);
delete this._messages[clientId];
@@ -34,79 +34,79 @@ Faye.Engine.Memory.prototype = {
this._server.trigger('disconnect', clientId);
if (callback) callback.call(context);
},
-
+
clientExists: function(clientId, callback, context) {
callback.call(context, this._namespace.exists(clientId));
},
-
+
ping: function(clientId) {
var timeout = this._server.timeout;
if (typeof timeout !== 'number') return;
-
+
this._server.debug('Ping ?, ?', clientId, timeout);
this.removeTimeout(clientId);
this.addTimeout(clientId, 2 * timeout, function() {
this.destroyClient(clientId);
}, this);
},
-
+
subscribe: function(clientId, channel, callback, context) {
var clients = this._clients, channels = this._channels;
-
+
clients[clientId] = clients[clientId] || new Faye.Set();
var trigger = clients[clientId].add(channel);
-
+
channels[channel] = channels[channel] || new Faye.Set();
channels[channel].add(clientId);
-
+
this._server.debug('Subscribed client ? to channel ?', clientId, channel);
if (trigger) this._server.trigger('subscribe', clientId, channel);
if (callback) callback.call(context, true);
},
-
+
unsubscribe: function(clientId, channel, callback, context) {
var clients = this._clients,
channels = this._channels,
trigger = false;
-
+
if (clients[clientId]) {
trigger = clients[clientId].remove(channel);
if (clients[clientId].isEmpty()) delete clients[clientId];
}
-
+
if (channels[channel]) {
channels[channel].remove(clientId);
if (channels[channel].isEmpty()) delete channels[channel];
}
-
+
this._server.debug('Unsubscribed client ? from channel ?', clientId, channel);
if (trigger) this._server.trigger('unsubscribe', clientId, channel);
if (callback) callback.call(context, true);
},
-
+
publish: function(message, channels) {
this._server.debug('Publishing message ?', message);
var messages = this._messages,
clients = new Faye.Set(),
subs;
-
+
for (var i = 0, n = channels.length; i < n; i++) {
subs = this._channels[channels[i]];
if (!subs) continue;
subs.forEach(clients.add, clients);
}
-
+
clients.forEach(function(clientId) {
this._server.debug('Queueing for client ?: ?', clientId, message);
messages[clientId] = messages[clientId] || [];
messages[clientId].push(Faye.copyObject(message));
this.emptyQueue(clientId);
}, this);
-
+
this._server.trigger('publish', message.clientId, message.channel, message.data);
},
-
+
emptyQueue: function(clientId) {
if (!this._server.hasConnection(clientId)) return;
this._server.deliver(clientId, this._messages[clientId]);
View
36 javascript/engines/proxy.js
@@ -2,7 +2,7 @@ Faye.Engine = {
get: function(options) {
return new Faye.Engine.Proxy(options);
},
-
+
METHODS: ['createClient', 'clientExists', 'destroyClient', 'ping', 'subscribe', 'unsubscribe']
};
@@ -10,26 +10,26 @@ Faye.Engine.Proxy = Faye.Class({
MAX_DELAY: <%= Faye::Engine::MAX_DELAY %>,
INTERVAL: <%= Faye::Engine::INTERVAL %>,
TIMEOUT: <%= Faye::Engine::TIMEOUT %>,
-
+
className: 'Engine',
-
+
initialize: function(options) {
this._options = options || {};
this._connections = {};
this.interval = this._options.interval || this.INTERVAL;
this.timeout = this._options.timeout || this.TIMEOUT;
-
+
var engineClass = this._options.type || Faye.Engine.Memory;
this._engine = engineClass.create(this, this._options);
-
+
this.bind('disconnect', function(clientId) {
var self = this;
setTimeout(function() { self.closeConnection(clientId) }, 10);
}, this);
-
+
this.debug('Created new engine: ?', this._options);
},
-
+
connect: function(clientId, options, callback, context) {
this.debug('Accepting connection from ?', clientId);
this._engine.ping(clientId);
@@ -37,11 +37,11 @@ Faye.Engine.Proxy = Faye.Class({
conn.connect(options, callback, context);
this._engine.emptyQueue(clientId);
},
-
+
hasConnection: function(clientId) {
return this._connections.hasOwnProperty(clientId);
},
-
+
connection: function(clientId, create) {
var conn = this._connections[clientId];
if (conn || !create) return conn;
@@ -49,7 +49,7 @@ Faye.Engine.Proxy = Faye.Class({
this.trigger('connection:open', clientId);
return this._connections[clientId];
},
-
+
closeConnection: function(clientId) {
this.debug('Closing connection for ?', clientId);
var conn = this._connections[clientId];
@@ -58,40 +58,40 @@ Faye.Engine.Proxy = Faye.Class({
this.trigger('connection:close', clientId);
delete this._connections[clientId];
},
-
+
openSocket: function(clientId, socket) {
if (!clientId) return;
var conn = this.connection(clientId, true);
conn.socket = socket;
},
-
+
deliver: function(clientId, messages) {
if (!messages || messages.length === 0) return false;
-
+
var conn = this.connection(clientId, false);
if (!conn) return false;
-
+
for (var i = 0, n = messages.length; i < n; i++) {
conn.deliver(messages[i]);
}
return true;
},
-
+
generateId: function() {
return Faye.random();
},
-
+
flush: function(clientId) {
if (!clientId) return;
this.debug('Flushing connection queue for ?', clientId);
var conn = this.connection(clientId, false);
if (conn) conn.flush(true);
},
-
+
disconnect: function() {
if (this._engine.disconnect) return this._engine.disconnect();
},
-
+
publish: function(message) {
var channels = Faye.Channel.expand(message.channel);
return this._engine.publish(message, channels);
View
4 javascript/error.js
@@ -4,7 +4,7 @@ Faye.Error = Faye.Class({
this.params = Array.prototype.slice.call(params);
this.message = message;
},
-
+
toString: function() {
return this.code + ':' +
this.params.join(',') + ':' +
@@ -36,7 +36,7 @@ Faye.Error.parse = function(message) {
EXT_UNKNOWN
PUBLISH_FAILED
SERVER_ERROR ].each do |error_type|
-
+
code, message = Faye::Error.const_get(error_type)
js_method = error_type.downcase.gsub(/_(.)/) { $1.upcase }
%>
View
40 javascript/faye.js
@@ -14,16 +14,16 @@ Faye.extend = function(dest, source, overwrite) {
Faye.extend(Faye, {
VERSION: '<%= Faye::VERSION %>',
-
+
BAYEUX_VERSION: '<%= Faye::BAYEUX_VERSION %>',
ID_LENGTH: <%= Faye::Engine::ID_LENGTH %>,
JSONP_CALLBACK: '<%= Faye::JSONP_CALLBACK %>',
CONNECTION_TYPES: ['long-polling', 'cross-origin-long-polling', 'callback-polling', 'websocket', 'eventsource', 'in-process'],
-
+
MANDATORY_CONNECTION_TYPES: ['long-polling', 'callback-polling', 'in-process'],
-
+
ENV: (function() { return this })(),
-
+
random: function(bitlength) {
bitlength = bitlength || this.ID_LENGTH;
if (bitlength > 32) {
@@ -37,16 +37,16 @@ Faye.extend(Faye, {
var limit = Math.pow(2, bitlength) - 1,
maxSize = limit.toString(36).length,
string = Math.floor(Math.random() * limit).toString(36);
-
+
while (string.length < maxSize) string = '0' + string;
return string;
},
-
+
clientIdFromMessages: function(messages) {
var first = [].concat(messages)[0];
return first && first.clientId;
},
-
+
copyObject: function(object) {
var clone, i, key;
if (object instanceof Array) {
@@ -62,7 +62,7 @@ Faye.extend(Faye, {
return object;
}
},
-
+
commonElement: function(lista, listb) {
for (var i = 0, n = lista.length; i < n; i++) {
if (this.indexOf(listb, lista[i]) !== -1)
@@ -70,20 +70,20 @@ Faye.extend(Faye, {
}
return null;
},
-
+
indexOf: function(list, needle) {
if (list.indexOf) return list.indexOf(needle);
-
+
for (var i = 0, n = list.length; i < n; i++) {
if (list[i] === needle) return i;
}
return -1;
},
-
+
map: function(object, callback, context) {
if (object.map) return object.map(callback, context);
var result = [];
-
+
if (object instanceof Array) {
for (var i = 0, n = object.length; i < n; i++) {
result.push(callback.call(context || null, object[i], i));
@@ -96,7 +96,7 @@ Faye.extend(Faye, {
}
return result;
},
-
+
filter: function(array, callback, context) {
var result = [];
for (var i = 0, n = array.length; i < n; i++) {
@@ -105,7 +105,7 @@ Faye.extend(Faye, {
}
return result;
},
-
+
asyncEach: function(list, iterator, callback, context) {
var n = list.length,
i = -1,
@@ -132,7 +132,7 @@ Faye.extend(Faye, {
};
resume();
},
-
+
// http://assanka.net/content/tech/2009/09/02/json2-js-vs-prototype/
toJSON: function(object) {
if (this.stringify)
@@ -141,14 +141,14 @@ Faye.extend(Faye, {
? this[key]
: value;
});
-
+
return JSON.stringify(object);
},
-
+
logger: function(message) {
if (typeof console !== 'undefined') console.log(message);
},
-
+
timestamp: function() {
var date = new Date(),
year = date.getFullYear(),
@@ -157,11 +157,11 @@ Faye.extend(Faye, {
hour = date.getHours(),
minute = date.getMinutes(),
second = date.getSeconds();
-
+
var pad = function(n) {
return n < 10 ? '0' + n : String(n);
};
-
+
return pad(year) + '-' + pad(month) + '-' + pad(day) + ' ' +
pad(hour) + ':' + pad(minute) + ':' + pad(second);
}
View
16 javascript/mixins/deferrable.js
@@ -1,14 +1,14 @@
Faye.Deferrable = {
callback: function(callback, context) {
if (!callback) return;
-
+
if (this._deferredStatus === 'succeeded')
return callback.apply(context, this._deferredArgs);
-
+
this._callbacks = this._callbacks || [];
this._callbacks.push([callback, context]);
},
-
+
timeout: function(seconds, message) {
var _this = this;
var timer = Faye.ENV.setTimeout(function() {
@@ -16,7 +16,7 @@ Faye.Deferrable = {
}, seconds * 1000);
this._timer = timer;
},
-
+
errback: function(callback, context) {
if (!callback) return;
@@ -34,17 +34,17 @@ Faye.Deferrable = {
var args = Array.prototype.slice.call(arguments),
status = args.shift(),
callbacks;
-
+
this._deferredStatus = status;
this._deferredArgs = args;
-
+
if (status === 'succeeded')
callbacks = this._callbacks;
else if (status === 'failed')
callbacks = this._errbacks;
-
+
if (!callbacks) return;
-
+
var callback;
while (callback = callbacks.shift())
callback[0].apply(callback[1], this._deferredArgs);
View
14 javascript/mixins/logging.js
@@ -5,19 +5,19 @@ Faye.Logging = {
info: 1,
debug: 0
},
-
+
logLevel: 'error',
-
+
log: function(messageArgs, level) {
if (!Faye.logger) return;
-
+
var levels = Faye.Logging.LOG_LEVELS;
if (levels[Faye.Logging.logLevel] > levels[level]) return;
-
+
var messageArgs = Array.prototype.slice.apply(messageArgs),
banner = ' [' + level.toUpperCase() + '] [Faye',
klass = this.className,
-
+
message = messageArgs.shift().replace(/\?/g, function() {
try {
return Faye.toJSON(messageArgs.shift());
@@ -25,7 +25,7 @@ Faye.Logging = {
return '[Object]';
}
});
-
+
for (var key in Faye) {
if (klass) continue;
if (typeof Faye[key] !== 'function') continue;
@@ -33,7 +33,7 @@ Faye.Logging = {
}
if (klass) banner += '.' + klass;
banner += '] ';
-
+
Faye.logger(Faye.timestamp() + banner + message);
}
};
View
16 javascript/mixins/publisher.js
@@ -3,39 +3,39 @@ Faye.Publisher = {
if (!this._subscribers || !this._subscribers[eventType]) return 0;
return this._subscribers[eventType].length;
},
-
+
bind: function(eventType, listener, context) {
this._subscribers = this._subscribers || {};
var list = this._subscribers[eventType] = this._subscribers[eventType] || [];
list.push([listener, context]);
},
-
+
unbind: function(eventType, listener, context) {
if (!this._subscribers || !this._subscribers[eventType]) return;
-
+
if (!listener) {
delete this._subscribers[eventType];
return;
}
var list = this._subscribers[eventType],
i = list.length;
-
+
while (i--) {
if (listener !== list[i][0]) continue;
if (context && list[i][1] !== context) continue;
list.splice(i,1);
}
},
-
+
trigger: function() {
var args = Array.prototype.slice.call(arguments),
eventType = args.shift();
-
+
if (!this._subscribers || !this._subscribers[eventType]) return;
-
+
var listeners = this._subscribers[eventType].slice(),
listener;
-
+
for (var i = 0, n = listeners.length; i < n; i++) {
listener = listeners[i];
listener[0].apply(listener[1], args);
View
2  javascript/mixins/timeouts.js
@@ -8,7 +8,7 @@ Faye.Timeouts = {
callback.call(context);
}, 1000 * delay);
},
-
+
removeTimeout: function(name) {
this._timeouts = this._timeouts || {};
var timeout = this._timeouts[name];
View
44 javascript/protocol/channel.js
@@ -2,11 +2,11 @@ Faye.Channel = Faye.Class({
initialize: function(name) {
this.id = this.name = name;
},
-
+
push: function(message) {
this.trigger('message', message);
},
-
+
isUnused: function() {
return this.countListeners('message') === 0;
}
@@ -20,75 +20,75 @@ Faye.extend(Faye.Channel, {
SUBSCRIBE: '<%= Faye::Channel::SUBSCRIBE %>',
UNSUBSCRIBE: '<%= Faye::Channel::UNSUBSCRIBE %>',
DISCONNECT: '<%= Faye::Channel::DISCONNECT %>',
-
+
META: '<%= Faye::Channel::META %>',
SERVICE: '<%= Faye::Channel::SERVICE %>',
-
+
expand: function(name) {
var segments = this.parse(name),
channels = ['/**', name];
-
+
var copy = segments.slice();
copy[copy.length - 1] = '*';
channels.push(this.unparse(copy));
-
+
for (var i = 1, n = segments.length; i < n; i++) {
copy = segments.slice(0, i);
copy.push('**');
channels.push(this.unparse(copy));
}
-
+
return channels;
},
-
+
isValid: function(name) {
return Faye.Grammar.CHANNEL_NAME.test(name) ||
Faye.Grammar.CHANNEL_PATTERN.test(name);
},
-
+
parse: function(name) {
if (!this.isValid(name)) return null;
return name.split('/').slice(1);
},
-
+
unparse: function(segments) {
return '/' + segments.join('/');
},
-
+
isMeta: function(name) {
var segments = this.parse(name);
return segments ? (segments[0] === this.META) : null;
},
-
+
isService: function(name) {
var segments = this.parse(name);
return segments ? (segments[0] === this.SERVICE) : null;
},
-
+
isSubscribable: function(name) {
if (!this.isValid(name)) return null;
return !this.isMeta(name) && !this.isService(name);
},
-
+
Set: Faye.Class({
initialize: function() {
this._channels = {};
},
-
+
getKeys: function() {
var keys = [];
for (var key in this._channels) keys.push(key);
return keys;
},
-
+
remove: function(name) {
delete this._channels[name];
},
-
+
hasSubscription: function(name) {
return this._channels.hasOwnProperty(name);
},
-
+
subscribe: function(names, callback, context) {
if (!callback) return;
var name;
@@ -98,12 +98,12 @@ Faye.extend(Faye.Channel, {
channel.bind('message', callback, context);
}
},
-
+
unsubscribe: function(name, callback, context) {
var channel = this._channels[name];
if (!channel) return false;
channel.unbind('message', callback, context);
-
+
if (channel.isUnused()) {
this.remove(name);
return true;
@@ -111,10 +111,10 @@ Faye.extend(Faye.Channel, {
return false;
}
},
-
+
distributeMessage: function(message) {
var channels = Faye.Channel.expand(message.channel);
-
+
for (var i = 0, n = channels.length; i < n; i++) {
var channel = this._channels[channels[i]];
if (channel) channel.trigger('message', message.data);
View
136 javascript/protocol/client.js
@@ -3,20 +3,20 @@ Faye.Client = Faye.Class({
CONNECTING: <%= Faye::Client::CONNECTING %>,
CONNECTED: <%= Faye::Client::CONNECTED %>,
DISCONNECTED: <%= Faye::Client::DISCONNECTED %>,
-
+
HANDSHAKE: '<%= Faye::Client::HANDSHAKE %>',
RETRY: '<%= Faye::Client::RETRY %>',
NONE: '<%= Faye::Client::NONE %>',
-
+
CONNECTION_TIMEOUT: <%= Faye::Client::CONNECTION_TIMEOUT %>,
DEFAULT_RETRY: <%= Faye::Client::DEFAULT_RETRY %>,
-
+
DEFAULT_ENDPOINT: '<%= Faye::RackAdapter::DEFAULT_ENDPOINT %>',
INTERVAL: <%= Faye::Engine::INTERVAL %>,
-
+
initialize: function(endpoint, options) {
this.info('New client created for ?', endpoint);
-
+
this._options = options || {};
this.endpoint = endpoint || this.DEFAULT_ENDPOINT;
this.endpoints = this._options.endpoints || {};
@@ -25,36 +25,36 @@ Faye.Client = Faye.Class({
this._headers = {};
this._disabled = [];
this.retry = this._options.retry || this.DEFAULT_RETRY;
-
+
this._selectTransport(Faye.MANDATORY_CONNECTION_TYPES);
-
+
this._state = this.UNCONNECTED;
this._channels = new Faye.Channel.Set();
this._messageId = 0;
-
+
this._responseCallbacks = {};
-
+
this._advice = {
reconnect: this.RETRY,
interval: 1000 * (this._options.interval || this.INTERVAL),
timeout: 1000 * (this._options.timeout || this.CONNECTION_TIMEOUT)
};
-
+
if (Faye.Event)
Faye.Event.on(Faye.ENV, 'beforeunload', function() {
if (Faye.indexOf(this._disabled, 'autodisconnect') < 0)
this.disconnect();
}, this);
},
-
+
disable: function(feature) {
this._disabled.push(feature);
},
-
+
setHeader: function(name, value) {
this._headers[name] = value;
},
-
+
getClientId: function() {
return this._clientId;
},
@@ -90,33 +90,33 @@ Faye.Client = Faye.Class({
handshake: function(callback, context) {
if (this._advice.reconnect === this.NONE) return;
if (this._state !== this.UNCONNECTED) return;
-
+
this._state = this.CONNECTING;
var self = this;
-
+
this.info('Initiating handshake with ?', this.endpoint);
-
+
this._send({
channel: Faye.Channel.HANDSHAKE,
version: Faye.BAYEUX_VERSION,
supportedConnectionTypes: [this._transport.connectionType]
-
+
}, function(response) {
-
+
if (response.successful) {
this._state = this.CONNECTED;
this._clientId = response.clientId;
-
+
var connectionTypes = Faye.filter(response.supportedConnectionTypes, function(connType) {
return Faye.indexOf(this._disabled, connType) < 0;
}, this);
this._selectTransport(connectionTypes);
-
+
this.info('Handshake successful: ?', this._clientId);
-
+
this.subscribe(this._channels.getKeys(), true);
if (callback) callback.call(context);
-
+
} else {
this.info('Handshake unsuccessful');
Faye.ENV.setTimeout(function() { self.handshake(callback, context) }, this._advice.interval);
@@ -124,7 +124,7 @@ Faye.Client = Faye.Class({
}
}, this);
},
-
+
// Request Response
// MUST include: * channel MUST include: * channel
// * clientId * successful
@@ -137,30 +137,30 @@ Faye.Client = Faye.Class({
connect: function(callback, context) {
if (this._advice.reconnect === this.NONE) return;
if (this._state === this.DISCONNECTED) return;
-
+
if (this._state === this.UNCONNECTED)
return this.handshake(function() { this.connect(callback, context) }, this);
-
+
this.callback(callback, context);
if (this._state !== this.CONNECTED) return;
-
+
this.info('Calling deferred actions for ?', this._clientId);
this.setDeferredStatus('succeeded');
this.setDeferredStatus('deferred');
-
+
if (this._connectRequest) return;
this._connectRequest = true;
-
+
this.info('Initiating connection for ?', this._clientId);
-
+
this._send({
channel: Faye.Channel.CONNECT,
clientId: this._clientId,
connectionType: this._transport.connectionType
-
+
}, this._cycleConnection, this);
},
-
+
// Request Response
// MUST include: * channel MUST include: * channel
// * clientId * successful
@@ -171,21 +171,21 @@ Faye.Client = Faye.Class({
disconnect: function() {
if (this._state !== this.CONNECTED) return;
this._state = this.DISCONNECTED;
-
+
this.info('Disconnecting ?', this._clientId);
-
+
this._send({
channel: Faye.Channel.DISCONNECT,
clientId: this._clientId
-
+
}, function(response) {
if (response.successful) this._transport.close();
}, this);
-
+
this.info('Clearing channel listeners for ?', this._clientId);
this._channels = new Faye.Channel.Set();
},
-
+
// Request Response
// MUST include: * channel MUST include: * channel
// * clientId * successful
@@ -201,41 +201,41 @@ Faye.Client = Faye.Class({
return Faye.map(channel, function(c) {
return this.subscribe(c, callback, context);
}, this);
-
+
var subscription = new Faye.Subscription(this, channel, callback, context),
force = (callback === true),
hasSubscribe = this._channels.hasSubscription(channel);
-
+
if (hasSubscribe && !force) {
this._channels.subscribe([channel], callback, context);
subscription.setDeferredStatus('succeeded');
return subscription;
}
-
+
this.connect(function() {
this.info('Client ? attempting to subscribe to ?', this._clientId, channel);
if (!force) this._channels.subscribe([channel], callback, context);
-
+
this._send({
channel: Faye.Channel.SUBSCRIBE,
clientId: this._clientId,
subscription: channel
-
+
}, function(response) {
if (!response.successful) {
subscription.setDeferredStatus('failed', Faye.Error.parse(response.error));
return this._channels.unsubscribe(channel, callback, context);
}
-
+
var channels = [].concat(response.subscription);
this.info('Subscription acknowledged for ? to ?', this._clientId, channels);
subscription.setDeferredStatus('succeeded');
}, this);
}, this);
-
+
return subscription;
},
-
+
// Request Response
// MUST include: * channel MUST include: * channel
// * clientId * successful
@@ -251,27 +251,27 @@ Faye.Client = Faye.Class({
return Faye.map(channel, function(c) {
return this.unsubscribe(c, callback, context);
}, this);
-
+
var dead = this._channels.unsubscribe(channel, callback, context);
if (!dead) return;
-
+
this.connect(function() {
this.info('Client ? attempting to unsubscribe from ?', this._clientId, channel);
-
+
this._send({
channel: Faye.Channel.UNSUBSCRIBE,
clientId: this._clientId,
subscription: channel
-
+
}, function(response) {
if (!response.successful) return;
-
+
var channels = [].concat(response.subscription);
this.info('Unsubscription acknowledged for ? from ?', this._clientId, channels);
}, this);
}, this);
},
-
+
// Request Response
// MUST include: * channel MUST include: * channel
// * data * successful
@@ -280,10 +280,10 @@ Faye.Client = Faye.Class({
// * ext * ext
publish: function(channel, data) {
var publication = new Faye.Publication();
-
+
this.connect(function() {
this.info('Client ? queueing published message to ?: ?', this._clientId, channel, data);
-
+
this._send({
channel: channel,
data: data,
@@ -295,44 +295,44 @@ Faye.Client = Faye.Class({
publication.setDeferredStatus('failed', Faye.Error.parse(response.error));
}, this);
}, this);
-
+
return publication;
},
-
+
receiveMessage: function(message) {
this.pipeThroughExtensions('incoming', message, function(message) {
if (!message) return;
-
+
if (message.advice) this._handleAdvice(message.advice);
this._deliverMessage(message);
-
+
if (message.successful === undefined) return;
-
+
var callback = this._responseCallbacks[message.id];
if (!callback) return;
-
+
delete this._responseCallbacks[message.id];
callback[0].call(callback[1], message);
}, this);
},
-
+
_selectTransport: function(transportTypes) {
Faye.Transport.get(this, transportTypes, function(transport) {
this.debug('Selected ? transport for ?', transport.connectionType, transport.endpoint);
-
+
if (transport === this._transport) return;
if (this._transport) this._transport.close();
this._transport = transport;
this._transport.cookies = this._cookies;
this._transport.headers = this._headers;
-
+
transport.bind('down', function() {
if (this._transportUp !== undefined && !this._transportUp) return;
this._transportUp = false;
this.trigger('transport:down');
}, this);
-
+
transport.bind('up', function() {
if (this._transportUp !== undefined && this._transportUp) return;
this._transportUp = true;
@@ -340,7 +340,7 @@ Faye.Client = Faye.Class({
}, this);
}, this);
},
-
+
_send: function(message, callback, context) {
message.id = this._generateMessageId();
if (callback) this._responseCallbacks[message.id] = [callback, context];
@@ -350,7 +350,7 @@ Faye.Client = Faye.Class({
this._transport.send(message, this._advice.timeout / 1000);
}, this);
},
-
+
_generateMessageId: function() {
this._messageId += 1;
if (this._messageId >= Math.pow(2,32)) this._messageId = 0;
@@ -359,26 +359,26 @@ Faye.Client = Faye.Class({
_handleAdvice: function(advice) {
Faye.extend(this._advice, advice);
-
+
if (this._advice.reconnect === this.HANDSHAKE && this._state !== this.DISCONNECTED) {
this._state = this.UNCONNECTED;
this._clientId = null;
this._cycleConnection();
}
},
-
+
_deliverMessage: function(message) {
if (!message.channel || message.data === undefined) return;
this.info('Client ? calling listeners for ? with ?', this._clientId, message.channel, message.data);
this._channels.distributeMessage(message);
},
-
+
_teardownConnection: function() {
if (!this._connectRequest) return;
this._connectRequest = null;
this.info('Closed connection for ?', this._clientId);
},