* Use raw web sockets instead of socket.io. closes #114 * promote most plugin code to be actually integrated with groovebasin, except last.fm * ability to upgrade from mpd protocol to groovebasin protocol * serialize/deserialize lastQueueDate and update it for all types of queuing. Fixes DynamicMode losing randomness data on server restart. * repeat state is saved between restarts * fixed a race condition in player.importFile * a smaller subset of db file properties are sent to the server, reducing library payload size * diffs are sent to client for playlist and library. closes #142 * information is no longer requested in the groovebasin API; it is only subscribed to. closes #115 * all commands go through the permissions framework. see #37 * chat is deleted for now. closes #17 * update to latest superagent and leveldb * fix stream activating and deactivating when seeking and not streaming
61 lines
1.6 KiB
JavaScript
61 lines
1.6 KiB
JavaScript
var Duplex = require('stream').Duplex;
|
|
var util = require('util');
|
|
|
|
module.exports = ProtocolParser;
|
|
|
|
util.inherits(ProtocolParser, Duplex);
|
|
function ProtocolParser(options) {
|
|
var streamOptions = extend(extend({}, options.streamOptions || {}), {decodeStrings: false});
|
|
Duplex.call(this, streamOptions);
|
|
this.player = options.player;
|
|
|
|
this.buffer = "";
|
|
}
|
|
|
|
ProtocolParser.prototype._read = function(size) {}
|
|
|
|
ProtocolParser.prototype._write = function(chunk, encoding, callback) {
|
|
var self = this;
|
|
|
|
var lines = chunk.split("\n");
|
|
self.buffer += lines[0];
|
|
if (lines.length === 1) return callback();
|
|
handleLine(self.buffer);
|
|
var lastIndex = lines.length - 1;
|
|
for (var i = 1; i < lastIndex; i += 1) {
|
|
handleLine(lines[i]);
|
|
}
|
|
self.buffer = lines[lastIndex];
|
|
callback();
|
|
|
|
function handleLine(line) {
|
|
var jsonObject;
|
|
try {
|
|
jsonObject = JSON.parse(line);
|
|
} catch (err) {
|
|
console.warn("received invalid json:", err.message);
|
|
self.sendMessage("error", "invalid json: " + err.message);
|
|
return;
|
|
}
|
|
if (typeof jsonObject !== 'object') {
|
|
console.warn("received json not an object:", jsonObject);
|
|
self.sendMessage("error", "expected json object");
|
|
return;
|
|
}
|
|
self.emit('message', jsonObject.name, jsonObject.args);
|
|
}
|
|
}
|
|
|
|
ProtocolParser.prototype.sendMessage = function(name, args) {
|
|
var jsonObject = {name: name, args: args};
|
|
this.push(JSON.stringify(jsonObject));
|
|
};
|
|
|
|
ProtocolParser.prototype.close = function() {
|
|
this.push(null);
|
|
};
|
|
|
|
function extend(o, src) {
|
|
for (var key in src) o[key] = src[key];
|
|
return o;
|
|
}
|