mirror of
https://github.com/viq/NewsBlur.git
synced 2025-08-05 16:49:45 +00:00
242 lines
4.6 KiB
JavaScript
242 lines
4.6 KiB
JavaScript
/**
|
|
* socket.io
|
|
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
|
|
* MIT Licensed
|
|
*/
|
|
|
|
(function (exports, io) {
|
|
|
|
/**
|
|
* Expose constructor.
|
|
*/
|
|
|
|
exports.SocketNamespace = SocketNamespace;
|
|
|
|
/**
|
|
* Socket namespace constructor.
|
|
*
|
|
* @constructor
|
|
* @api public
|
|
*/
|
|
|
|
function SocketNamespace (socket, name) {
|
|
this.socket = socket;
|
|
this.name = name || '';
|
|
this.flags = {};
|
|
this.json = new Flag(this, 'json');
|
|
this.ackPackets = 0;
|
|
this.acks = {};
|
|
};
|
|
|
|
/**
|
|
* Apply EventEmitter mixin.
|
|
*/
|
|
|
|
io.util.mixin(SocketNamespace, io.EventEmitter);
|
|
|
|
/**
|
|
* Copies emit since we override it
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
SocketNamespace.prototype.$emit = io.EventEmitter.prototype.emit;
|
|
|
|
/**
|
|
* Creates a new namespace, by proxying the request to the socket. This
|
|
* allows us to use the synax as we do on the server.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
SocketNamespace.prototype.of = function () {
|
|
return this.socket.of.apply(this.socket, arguments);
|
|
};
|
|
|
|
/**
|
|
* Sends a packet.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
SocketNamespace.prototype.packet = function (packet) {
|
|
packet.endpoint = this.name;
|
|
this.socket.packet(packet);
|
|
this.flags = {};
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Sends a message
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
SocketNamespace.prototype.send = function (data, fn) {
|
|
var packet = {
|
|
type: this.flags.json ? 'json' : 'message'
|
|
, data: data
|
|
};
|
|
|
|
if ('function' == typeof fn) {
|
|
packet.id = ++this.ackPackets;
|
|
packet.ack = true;
|
|
this.acks[packet.id] = fn;
|
|
}
|
|
|
|
return this.packet(packet);
|
|
};
|
|
|
|
/**
|
|
* Emits an event
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
SocketNamespace.prototype.emit = function (name) {
|
|
var args = Array.prototype.slice.call(arguments, 1)
|
|
, lastArg = args[args.length - 1]
|
|
, packet = {
|
|
type: 'event'
|
|
, name: name
|
|
};
|
|
|
|
if ('function' == typeof lastArg) {
|
|
packet.id = ++this.ackPackets;
|
|
packet.ack = 'data';
|
|
this.acks[packet.id] = lastArg;
|
|
args = args.slice(0, args.length - 1);
|
|
}
|
|
|
|
packet.args = args;
|
|
|
|
return this.packet(packet);
|
|
};
|
|
|
|
/**
|
|
* Disconnects the namespace
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
SocketNamespace.prototype.disconnect = function () {
|
|
if (this.name === '') {
|
|
this.socket.disconnect();
|
|
} else {
|
|
this.packet({ type: 'disconnect' });
|
|
this.$emit('disconnect');
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Handles a packet
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
SocketNamespace.prototype.onPacket = function (packet) {
|
|
var self = this;
|
|
|
|
function ack () {
|
|
self.packet({
|
|
type: 'ack'
|
|
, args: io.util.toArray(arguments)
|
|
, ackId: packet.id
|
|
});
|
|
};
|
|
|
|
switch (packet.type) {
|
|
case 'connect':
|
|
this.$emit('connect');
|
|
break;
|
|
|
|
case 'disconnect':
|
|
if (this.name === '') {
|
|
this.socket.onDisconnect(packet.reason || 'booted');
|
|
} else {
|
|
this.$emit('disconnect', packet.reason);
|
|
}
|
|
break;
|
|
|
|
case 'message':
|
|
case 'json':
|
|
var params = ['message', packet.data];
|
|
|
|
if (packet.ack == 'data') {
|
|
params.push(ack);
|
|
} else if (packet.ack) {
|
|
this.packet({ type: 'ack', ackId: packet.id });
|
|
}
|
|
|
|
this.$emit.apply(this, params);
|
|
break;
|
|
|
|
case 'event':
|
|
var params = [packet.name].concat(packet.args);
|
|
|
|
if (packet.ack == 'data')
|
|
params.push(ack);
|
|
|
|
this.$emit.apply(this, params);
|
|
break;
|
|
|
|
case 'ack':
|
|
if (this.acks[packet.ackId]) {
|
|
this.acks[packet.ackId].apply(this, packet.args);
|
|
delete this.acks[packet.ackId];
|
|
}
|
|
break;
|
|
|
|
case 'error':
|
|
if (packet.advice){
|
|
this.socket.onError(packet);
|
|
} else {
|
|
if (packet.reason == 'unauthorized') {
|
|
this.$emit('connect_failed', packet.reason);
|
|
} else {
|
|
this.$emit('error', packet.reason);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Flag interface.
|
|
*
|
|
* @api private
|
|
*/
|
|
|
|
function Flag (nsp, name) {
|
|
this.namespace = nsp;
|
|
this.name = name;
|
|
};
|
|
|
|
/**
|
|
* Send a message
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
Flag.prototype.send = function () {
|
|
this.namespace.flags[this.name] = true;
|
|
this.namespace.send.apply(this.namespace, arguments);
|
|
};
|
|
|
|
/**
|
|
* Emit an event
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
Flag.prototype.emit = function () {
|
|
this.namespace.flags[this.name] = true;
|
|
this.namespace.emit.apply(this.namespace, arguments);
|
|
};
|
|
|
|
})(
|
|
'undefined' != typeof io ? io : module.exports
|
|
, 'undefined' != typeof io ? io : module.parent.exports
|
|
);
|