queue refactored, support for idle/noidle
This commit is contained in:
parent
5e5378923f
commit
783fa14351
5 changed files with 72 additions and 50 deletions
|
@ -1,6 +1,6 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<script>
|
||||
let ws = new WebSocket("ws://localhost:8080?server=0:6600");
|
||||
let ws = new WebSocket("ws://localhost:8080?server=:6600");
|
||||
</script>
|
||||
</html>
|
|
@ -1,4 +1,6 @@
|
|||
let httpServer = require("http").createServer();
|
||||
httpServer.listen(8080);
|
||||
|
||||
require("..").ws2mpd(httpServer);
|
||||
let mod = require("..");
|
||||
mod.logging(true);
|
||||
mod.ws2mpd(httpServer);
|
||||
|
|
29
index.js
29
index.js
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const commands = require("./commands");
|
||||
const log = require("./log.js").log;
|
||||
const Queue = require("./queue").Queue;
|
||||
|
||||
function initConnection(request) {
|
||||
let ws = request.accept();
|
||||
|
@ -16,47 +16,36 @@ function initConnection(request) {
|
|||
mpd.setTimeout(0);
|
||||
mpd.connect(port, host);
|
||||
|
||||
let commandQueue = [];
|
||||
let command = null;
|
||||
|
||||
function waitForCommand(cmd) {
|
||||
command = cmd;
|
||||
cmd.on("done", data => {
|
||||
// data coming from the response parser
|
||||
let queue = new Queue(mpd);
|
||||
queue.on("response", data => {
|
||||
log("ws <--", data);
|
||||
ws.send(JSON.stringify(data));
|
||||
command = null;
|
||||
processQueue();
|
||||
});
|
||||
}
|
||||
|
||||
function processQueue() {
|
||||
if (command || !commandQueue.length) { return; }
|
||||
let cmd = commands.create(mpd, commandQueue.shift());
|
||||
waitForCommand(cmd);
|
||||
}
|
||||
|
||||
// data going into the response parser
|
||||
ws.on("message", message => {
|
||||
log("ws -->", message.utf8Data);
|
||||
commandQueue.push(message.utf8Data);
|
||||
processQueue();
|
||||
queue.add(message.utf8Data);
|
||||
});
|
||||
|
||||
// client closes
|
||||
ws.on("close", (reasonCode, description) => {
|
||||
log(`ws ${ws.remoteAddress} disconnected`);
|
||||
mpd.end();
|
||||
});
|
||||
|
||||
// server closes
|
||||
mpd.on("close", () => {
|
||||
log("mpd disconnected");
|
||||
ws.close();
|
||||
});
|
||||
|
||||
// fail to conect
|
||||
mpd.on("error", () => {
|
||||
log("mpd connection error");
|
||||
ws.close();
|
||||
});
|
||||
|
||||
waitForCommand(commands.welcome(mpd));
|
||||
}
|
||||
|
||||
exports.logging = function(enabled) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ws2mpd",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const EventEmitter = require("events");
|
||||
const log = require("./log.js").log;
|
||||
|
||||
class Command extends EventEmitter {
|
||||
class Response extends EventEmitter {
|
||||
constructor(mpd) {
|
||||
super();
|
||||
this._mpd = mpd;
|
||||
|
@ -33,12 +33,10 @@ class Command extends EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
class Normal extends Command {
|
||||
constructor(mpd, command) {
|
||||
class Normal extends Response {
|
||||
constructor(mpd) {
|
||||
super(mpd);
|
||||
this._lines = [];
|
||||
log("--> mpd", command);
|
||||
mpd.write(command + "\n");
|
||||
}
|
||||
|
||||
_processBuffer() {
|
||||
|
@ -51,23 +49,22 @@ class Normal extends Command {
|
|||
}
|
||||
}
|
||||
|
||||
class Welcome extends Command {
|
||||
class Idle extends Normal {}
|
||||
|
||||
class Welcome extends Response {
|
||||
_processBuffer() {
|
||||
let line = this._getLine();
|
||||
if (line) { this._done([line]); }
|
||||
}
|
||||
}
|
||||
|
||||
class AlbumArt extends Command {
|
||||
constructor(mpd, command) {
|
||||
class Binary extends Response {
|
||||
constructor(mpd) {
|
||||
super(mpd);
|
||||
this._size = 0;
|
||||
this._binary = 0;
|
||||
this._data = null;
|
||||
this._lines = [];
|
||||
|
||||
log("--> mpd", command);
|
||||
mpd.write(command + "\n");
|
||||
}
|
||||
|
||||
_processBuffer() {
|
||||
|
@ -108,18 +105,52 @@ class AlbumArt extends Command {
|
|||
this._lines.push(line);
|
||||
this._done(this._lines);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.create = function(mpd, command) {
|
||||
if (command.startsWith("albumart")) {
|
||||
return new AlbumArt(mpd, command);
|
||||
} else {
|
||||
return new Normal(mpd, command);
|
||||
|
||||
exports.Queue = class extends EventEmitter {
|
||||
constructor(mpd) {
|
||||
super();
|
||||
this._mpd = mpd;
|
||||
this._waiting = [];
|
||||
this._current = null;
|
||||
|
||||
this._create(Welcome);
|
||||
}
|
||||
|
||||
add(str) {
|
||||
if (str == "noidle" && this._current instanceof Idle) {
|
||||
this._mpd.write(str + "\n");
|
||||
return;
|
||||
}
|
||||
this._waiting.push(str);
|
||||
this._process();
|
||||
}
|
||||
|
||||
_process() {
|
||||
if (this._current || !this._waiting.length) { return; }
|
||||
let str = this._waiting.shift();
|
||||
this._create(getCtor(str));
|
||||
log("--> mpd", str);
|
||||
this._mpd.write(str + "\n");
|
||||
}
|
||||
|
||||
_create(ctor) {
|
||||
let cmd = new ctor(this._mpd);
|
||||
this._current = cmd;
|
||||
|
||||
cmd.on("done", data => {
|
||||
this.emit("response", data);
|
||||
this._current = null;
|
||||
this._process();
|
||||
});
|
||||
}
|
||||
return new Normal(mpd, command);
|
||||
}
|
||||
|
||||
exports.welcome = function(mpd) {
|
||||
return new Welcome(mpd);
|
||||
function getCtor(command) {
|
||||
switch (true) {
|
||||
case command.startsWith("idle"): return Idle;
|
||||
case command.startsWith("albumart") || command.startsWith("readpicture"): return Binary;
|
||||
default: return Normal;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue