build/faye.js in faye-0.3.2 vs build/faye.js in faye-0.3.3

- old
+ new

@@ -10,11 +10,11 @@ } return dest; }; Faye.extend(Faye, { - VERSION: '0.3.2', + VERSION: '0.3.3', BAYEUX_VERSION: '1.0', ID_LENGTH: 128, JSONP_CALLBACK: 'jsonpcallback', CONNECTION_TYPES: ["long-polling", "callback-polling"], @@ -247,11 +247,11 @@ if (scope && list[i][1] !== scope) continue; list.splice(i,1); } }, - fire: function() { + trigger: function() { var args = Array.prototype.slice.call(arguments), eventType = args.shift(); if (!this._observers || !this._observers[eventType]) return; @@ -270,45 +270,43 @@ debug: 0 }, logLevel: 'error', - log: function(message, level) { + log: function(messageArgs, level) { if (!Faye.logger) return; var levels = Faye.Logging.LOG_LEVELS; if (levels[Faye.Logging.logLevel] > levels[level]) return; - var banner = '[' + level.toUpperCase() + '] [Faye', - klass = null; + var messageArgs = Array.prototype.slice.apply(messageArgs), + banner = ' [' + level.toUpperCase() + '] [Faye', + klass = null, + + message = messageArgs.shift().replace(/\?/g, function() { + return Faye.toJSON(messageArgs.shift()); + }); for (var key in Faye) { if (klass) continue; if (typeof Faye[key] !== 'function') continue; if (this instanceof Faye[key]) klass = key; } if (klass) banner += '.' + klass; banner += '] '; - Faye.logger(Faye.timestamp() + ' ' + banner + message); - }, - - error: function(message) { - this.log(message, 'error'); - }, - warn: function(message) { - this.log(message, 'warn'); - }, - info: function(message) { - this.log(message, 'info'); - }, - debug: function(message) { - this.log(message, 'debug'); + Faye.logger(Faye.timestamp() + banner + message); } }; +Faye.each(Faye.Logging.LOG_LEVELS, function(level, value) { + Faye.Logging[level] = function() { + this.log(arguments, level); + }; +}); + Faye.Timeouts = { addTimeout: function(name, delay, callback, scope) { this._timeouts = this._timeouts || {}; if (this._timeouts.hasOwnProperty(name)) return; var self = this; @@ -332,11 +330,11 @@ initialize: function(name) { this.__id = this.name = name; }, push: function(message) { - this.fire('message', message); + this.trigger('message', message); } }); Faye.extend(Faye.Channel.prototype, Faye.Observable); @@ -486,27 +484,25 @@ }); Faye.Transport = Faye.extend(Faye.Class({ initialize: function(client, endpoint) { - this.debug('Created new transport for ' + endpoint); + this.debug('Created new transport for ?', endpoint); this._client = client; this._endpoint = endpoint; }, send: function(message, callback, scope) { if (!(message instanceof Array) && !message.id) message.id = this._client._namespace.generate(); - this.debug('Client ' + this._client._clientId + - ' sending message to ' + this._endpoint + ': ' + - Faye.toJSON(message)); + this.debug('Client ? sending message to ?: ?', + this._client._clientId, this._endpoint, message); this.request(message, function(responses) { - this.debug('Client ' + this._client._clientId + - ' received from ' + this._endpoint + ': ' + - Faye.toJSON(responses)); + this.debug('Client ? received from ?: ?', + this._client._clientId, this._endpoint, responses); if (!callback) return; var messages = [], deliverable = true; Faye.each([].concat(responses), function(response) { @@ -576,27 +572,26 @@ DEFAULT_ENDPOINT: '/bayeux', MAX_DELAY: 0.1, INTERVAL: 1000.0, initialize: function(endpoint, options) { - this.info('New client created for ' + endpoint); + this.info('New client created for ?', endpoint); this._endpoint = endpoint || this.DEFAULT_ENDPOINT; this._options = options || {}; this._timeout = this._options.timeout || this.CONNECTION_TIMEOUT; this._transport = Faye.Transport.get(this); this._state = this.UNCONNECTED; this._namespace = new Faye.Namespace(); this._outbox = []; this._channels = new Faye.Channel.Tree(); - this._callbacks = []; this._advice = {reconnect: this.RETRY, interval: this.INTERVAL}; - if (!Faye.Event) return; - Faye.Event.on(Faye.ENV, 'beforeunload', this.disconnect, this); + if (Faye.Event) Faye.Event.on(Faye.ENV, 'beforeunload', + this.disconnect, this); }, // Request // MUST include: * channel // * version @@ -621,31 +616,32 @@ if (this._state !== this.UNCONNECTED) return; this._state = this.CONNECTING; var self = this; - this.info('Initiating handshake with ' + this._endpoint); + this.info('Initiating handshake with ?', this._endpoint); this._transport.send({ channel: Faye.Channel.HANDSHAKE, version: Faye.BAYEUX_VERSION, supportedConnectionTypes: Faye.Transport.supportedConnectionTypes() }, function(response) { - if (!response.successful) { + if (response.successful) { + this._state = this.CONNECTED; + this._clientId = response.clientId; + this._transport = Faye.Transport.get(this, response.supportedConnectionTypes); + + this.info('Handshake successful: ?', this._clientId); + if (callback) callback.call(scope); + + } else { this.info('Handshake unsuccessful'); setTimeout(function() { self.handshake(callback, scope) }, this._advice.interval); - return this._state = this.UNCONNECTED; + this._state = this.UNCONNECTED; } - - this._state = this.CONNECTED; - this._clientId = response.clientId; - this._transport = Faye.Transport.get(this, response.supportedConnectionTypes); - - this.info('Handshake successful: ' + this._clientId); - if (callback) callback.call(scope); }, this); }, // Request Response // MUST include: * channel MUST include: * channel @@ -668,31 +664,31 @@ if (this._state === this.CONNECTING) return this.callback(callback, scope); if (this._state !== this.CONNECTED) return; - this.info('Calling deferred actions for ' + this._clientId); + this.info('Calling deferred actions for ?', this._clientId); this.setDeferredStatus('succeeded'); this.setDeferredStatus('deferred'); if (callback) callback.call(scope); if (this._connectionId) return; this._connectionId = this._namespace.generate(); var self = this; - this.info('Initiating connection for ' + this._clientId); + this.info('Initiating connection for ?', this._clientId); this._transport.send({ channel: Faye.Channel.CONNECT, clientId: this._clientId, connectionType: this._transport.connectionType, id: this._connectionId }, this._verifyClientId(function(response) { - delete this._connectionId; + this._connectionId = null; this.removeTimeout('reconnect'); - this.info('Closed connection for ' + this._clientId); + this.info('Closed connection for ?', this._clientId); setTimeout(function() { self.connect() }, this._advice.interval); })); this._beginReconnectTimeout(); }, @@ -706,19 +702,20 @@ // * id disconnect: function() { if (this._state !== this.CONNECTED) return; this._state = this.DISCONNECTED; - this.info('Disconnecting ' + this._clientId); + this.info('Disconnecting ?', this._clientId); this._transport.send({ channel: Faye.Channel.DISCONNECT, clientId: this._clientId }); - this.info('Clearing channel listeners for ' + this._clientId); + this.info('Clearing channel listeners for ?', this._clientId); this._channels = new Faye.Channel.Tree(); + this.removeTimeout('reconnect'); }, // Request Response // MUST include: * channel MUST include: * channel // * clientId * successful @@ -733,23 +730,21 @@ this.connect(function() { channels = [].concat(channels); this._validateChannels(channels); - this.info('Client ' + this._clientId + ' attempting to subscribe to [' + - channels.join(', ') + ']'); + this.info('Client ? attempting to subscribe to ?', this._clientId, channels); this._transport.send({ channel: Faye.Channel.SUBSCRIBE, clientId: this._clientId, subscription: channels }, this._verifyClientId(function(response) { if (!response.successful || !callback) return; - this.info('Subscription acknowledged for ' + this._clientId + ' to [' + - channels.join(', ') + ']'); + this.info('Subscription acknowledged for ? to ?', this._clientId, channels); channels = [].concat(response.subscription); Faye.each(channels, function(channel) { this._channels.set(channel, [callback, scope]); }, this); @@ -772,27 +767,25 @@ this.connect(function() { channels = [].concat(channels); this._validateChannels(channels); - this.info('Client ' + this._clientId + ' attempting to unsubscribe from [' + - channels.join(', ') + ']'); + this.info('Client ? attempting to unsubscribe from ?', this._clientId, channels); this._transport.send({ channel: Faye.Channel.UNSUBSCRIBE, clientId: this._clientId, subscription: channels }, this._verifyClientId(function(response) { if (!response.successful) return; - this.info('Unsubscription acknowledged for ' + this._clientId + ' from [' + - channels.join(', ') + ']'); - + this.info('Unsubscription acknowledged for ? from ?', this._clientId, channels); + channels = [].concat(response.subscription); Faye.each(channels, function(channel) { - this._channels.set(channel, null); + this._channels.set(channel, undefined); }, this); })); }, this); }, @@ -806,12 +799,11 @@ publish: function(channel, data) { this.connect(function() { this._validateChannels([channel]); - this.info('Client ' + this._clientId + ' queueing published message to ' + - channel + ': ' + Faye.toJSON(data)); + this.info('Client ? queueing published message to ?: ?', this._clientId, channel, data); this._enqueue({ channel: channel, data: data, clientId: this._clientId @@ -827,29 +819,27 @@ if (this._advice.reconnect === this.HANDSHAKE) this._clientId = null; }, deliverMessages: function(messages) { Faye.each(messages, function(message) { - this.info('Client ' + this._clientId + ' calling listeners for ' + - message.channel + ' with ' + Faye.toJSON(message.data)); + this.info('Client ? calling listeners for ? with ?', this._clientId, message.channel, message.data); var channels = this._channels.glob(message.channel); Faye.each(channels, function(callback) { - if (!callback) return; callback[0].call(callback[1], message.data); }); }, this); }, _beginReconnectTimeout: function() { this.addTimeout('reconnect', this._timeout, function() { - delete this._connectionId; - delete this._clientId; + this._connectionId = null; + this._clientId = null; this._state = this.UNCONNECTED; - this.info('Server took >' + this._timeout + 's to reply to connection for ' + - this._clientId + ': attempting to reconnect'); + this.info('Server took >?s to reply to connection for ?: attempting to reconnect', + this._timeout, this._clientId); this.subscribe(this._channels.getKeys()); }, this); }, @@ -933,24 +923,24 @@ Faye.Server = Faye.Class({ initialize: function(options) { this.info('New server created'); - this._options = options || {}; - this._channels = new Faye.Channel.Tree(); - this._clients = {}; - this._namespace = new Faye.Namespace(); + this._options = options || {}; + this._channels = new Faye.Channel.Tree(); + this._connections = {}; + this._namespace = new Faye.Namespace(); }, clientIds: function() { var ids = []; - Faye.each(this._clients, function(key, value) { ids.push(key) }); + Faye.each(this._connections, function(key, value) { ids.push(key) }); return ids; }, process: function(messages, local, callback) { - this.debug('Processing messages from ' + (local ? 'LOCAL' : 'REMOTE') + ' client'); + this.debug('Processing messages from ? client', local ? 'LOCAL' : 'REMOTE'); messages = [].concat(messages); var processed = 0, responses = []; Faye.each(messages, function(message) { @@ -964,63 +954,63 @@ }, flushConnection: function(messages) { messages = [].concat(messages); Faye.each(messages, function(message) { - var client = this._clients[message.clientId]; - if (client) client.flush(); + var connection = this._connections[message.clientId]; + if (connection) connection.flush(); }, this); }, _connection: function(id) { - if (this._clients.hasOwnProperty(id)) return this._clients[id]; - var client = new Faye.Connection(id, this._options); - client.on('staleClient', this._destroyClient, this); - return this._clients[id] = client; + if (this._connections.hasOwnProperty(id)) return this._connections[id]; + var connection = new Faye.Connection(id, this._options); + connection.on('staleConnection', this._destroyConnection, this); + return this._connections[id] = connection; }, - _destroyClient: function(client) { - client.disconnect(); - client.stopObserving('staleClient', this._destroyClient, this); - delete this._clients[client.id]; + _destroyConnection: function(connection) { + connection.disconnect(); + connection.stopObserving('staleConnection', this._destroyConnection, this); + delete this._connections[connection.id]; }, _handle: function(message, local, callback, scope) { - var channel = message.channel, + var channelName = message.channel, response; message.__id = Faye.random(); - Faye.each(this._channels.glob(channel), function(c) { - c.push(message); - this.info('Publishing message ' + Faye.toJSON(message.data) + - ' from client ' + clientId + ' to ' + c.name); + Faye.each(this._channels.glob(channelName), function(channel) { + channel.push(message); + this.info('Publishing message ? from client ? to ?', message.data, message.clientId, channel.name); }, this); - if (Faye.Channel.isMeta(channel)) { - response = this[Faye.Channel.parse(channel)[1]](message, local); + if (Faye.Channel.isMeta(channelName)) { + response = this[Faye.Channel.parse(channelName)[1]](message, local); var clientId = response.clientId; response.advice = response.advice || {}; Faye.extend(response.advice, { - reconnect: this._clients.hasOwnProperty(clientId) ? 'retry' : 'handshake', + reconnect: this._connections.hasOwnProperty(clientId) ? 'retry' : 'handshake', interval: Math.floor(Faye.Connection.prototype.INTERVAL * 1000) }, false); if (response.channel !== Faye.Channel.CONNECT || response.successful !== true) return callback.call(scope, response); - this.info('Accepting connection from ' + response.clientId); + this.info('Accepting connection from ?', response.clientId); + return this._connection(response.clientId).connect(function(events) { - this.info('Sending event messages to ' + response.clientId); - this.debug('Events for ' + response.clientId + ': ' + Faye.toJSON(events)); + this.info('Sending event messages to ?', response.clientId); + this.debug('Events for ?: ?', response.clientId, events); Faye.each(events, function(e) { delete e.__id }); callback.call(scope, [response].concat(events)); }, this); } - if (!message.clientId || Faye.Channel.isService(channel)) + if (!message.clientId || Faye.Channel.isService(channelName)) return callback([]); response = this._makeResponse(message); response.successful = true; callback(response); @@ -1066,56 +1056,56 @@ response.successful = !response.error; if (!response.successful) return response; var clientId = this._namespace.generate(); response.clientId = this._connection(clientId).id; - this.info('Accepting handshake from client ' + response.clientId); + this.info('Accepting handshake from client ?', response.clientId); return response; }, // MUST contain * clientId // * connectionType // MAY contain * ext // * id connect: function(message, local) { var response = this._makeResponse(message); - var clientId = message.clientId, - client = clientId ? this._clients[clientId] : null, + var clientId = message.clientId, + connection = clientId ? this._connections[clientId] : null, connectionType = message.connectionType; - if (!client) response.error = Faye.Error.clientUnknown(clientId); + if (!connection) response.error = Faye.Error.clientUnknown(clientId); if (!clientId) response.error = Faye.Error.parameterMissing('clientId'); if (!connectionType) response.error = Faye.Error.parameterMissing('connectionType'); response.successful = !response.error; if (!response.successful) delete response.clientId; if (!response.successful) return response; - response.clientId = client.id; + response.clientId = connection.id; return response; }, // MUST contain * clientId // MAY contain * ext // * id disconnect: function(message, local) { var response = this._makeResponse(message); - var clientId = message.clientId, - client = clientId ? this._clients[clientId] : null; + var clientId = message.clientId, + connection = clientId ? this._connections[clientId] : null; - if (!client) response.error = Faye.Error.clientUnknown(clientId); - if (!clientId) response.error = Faye.Error.parameterMissing('clientId'); + if (!connection) response.error = Faye.Error.clientUnknown(clientId); + if (!clientId) response.error = Faye.Error.parameterMissing('clientId'); response.successful = !response.error; if (!response.successful) delete response.clientId; if (!response.successful) return response; - this._destroyClient(client); + this._destroyConnection(connection); - this.info('Disconnected client: ' + clientId); + this.info('Disconnected client: ?', clientId); response.clientId = clientId; return response; }, // MUST contain * clientId @@ -1124,16 +1114,16 @@ // * id subscribe: function(message, local) { var response = this._makeResponse(message); var clientId = message.clientId, - client = clientId ? this._clients[clientId] : null, + connection = clientId ? this._connections[clientId] : null, subscription = message.subscription; subscription = [].concat(subscription); - if (!client) response.error = Faye.Error.clientUnknown(clientId); + if (!connection) response.error = Faye.Error.clientUnknown(clientId); if (!clientId) response.error = Faye.Error.parameterMissing('clientId'); if (!message.subscription) response.error = Faye.Error.parameterMissing('subscription'); response.subscription = subscription; @@ -1143,12 +1133,12 @@ if (!Faye.Channel.isValid(channel)) response.error = Faye.Error.channelInvalid(channel); if (response.error) return; channel = this._channels.findOrCreate(channel); - this.info('Subscribing client ' + clientId + ' to ' + channel.name); - client.subscribe(channel); + this.info('Subscribing client ? to ?', clientId, channel.name); + connection.subscribe(channel); }, this); response.successful = !response.error; return response; }, @@ -1159,30 +1149,32 @@ // * id unsubscribe: function(message, local) { var response = this._makeResponse(message); var clientId = message.clientId, - client = clientId ? this._clients[clientId] : null, + connection = clientId ? this._connections[clientId] : null, subscription = message.subscription; subscription = [].concat(subscription); - if (!client) response.error = Faye.Error.clientUnknown(clientId); + if (!connection) response.error = Faye.Error.clientUnknown(clientId); if (!clientId) response.error = Faye.Error.parameterMissing('clientId'); if (!message.subscription) response.error = Faye.Error.parameterMissing('subscription'); + response.subscription = subscription; + Faye.each(subscription, function(channel) { if (response.error) return; if (!Faye.Channel.isValid(channel)) return response.error = Faye.Error.channelInvalid(channel); channel = this._channels.get(channel); if (!channel) return; - this.info('Unsubscribing client ' + clientId + ' from ' + channel.name); - client.unsubscribe(channel); + this.info('Unsubscribing client ? from ?', clientId, channel.name); + connection.unsubscribe(channel); }, this); response.successful = !response.error; return response; } @@ -1263,11 +1255,11 @@ this.removeTimeout('connection'); this.removeTimeout('delivery'); this._connected = false; this.addTimeout('deletion', 10 * this.INTERVAL, function() { - this.fire('staleClient', this); + this.trigger('staleConnection', this); }, this); } }); Faye.extend(Faye.Connection.prototype, Faye.Deferrable); @@ -1392,13 +1384,13 @@ if (!this._endpointRe.test(requestUrl.pathname)) return false; if (/\.js$/.test(requestUrl.pathname)) { fs.readFile(this.SCRIPT_PATH, function(err, content) { - response.sendHeader(200, self.TYPE_SCRIPT); + response.writeHead(200, self.TYPE_SCRIPT); response.write(content); - response.close(); + response.end(); }); } else { var isGet = (request.method === 'GET'); @@ -1423,18 +1415,18 @@ if (isGet) this._server.flushConnection(message); this._server.process(message, false, function(replies) { var body = JSON.stringify(replies); if (isGet) body = jsonp + '(' + body + ');'; - response.sendHeader(200, type); + response.writeHead(200, type); response.write(body); - response.close(); + response.end(); }); } catch (e) { - response.sendHeader(400, this.TYPE_TEXT); + response.writeHead(400, this.TYPE_TEXT); response.write('Bad request'); - response.close(); + response.end(); } } }); exports.NodeAdapter = Faye.NodeAdapter; @@ -1449,16 +1441,18 @@ if (!callback) return; Faye.withDataFor(response, function(data) { callback.call(scope, JSON.parse(data)); }); }); - request.close(); + request.end(); }, createRequestForMessage: function(message) { var content = JSON.stringify(message), uri = url.parse(this._endpoint), client = http.createClient(uri.port, uri.hostname); + + client.addListener('error', function() { /* catch ECONNREFUSED */ }); if (parseInt(uri.port) === 443) client.setSecure('X509_PEM'); var request = client.request('POST', uri.pathname, { 'Content-Type': 'application/json', \ No newline at end of file