| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- const net = require('net');
- var clients = {};
- function Client(sock) {
- var _this = this;
- this.id = sock.remoteAddress;
- this.name = this.id;
- this.sock = sock;
- this.active = true;
- this.volumeControl = true;
- this.status = {
- battery: undefined,
- plugged: undefined,
- volume: undefined,
- lastUpdate: 0
- };
- this.ping = {
- duration: 0,
- lastUpdate: 0,
- pending: 0
- };
- this.sock.on('data', (data) => {
- var dataStr = data.toString("utf-8");
- dataStr.split(/[\r\n]/).forEach(i => i.length ? _this.onData(i) : i);
- });
- this.sock.on('close', () => {
- if (this.active) {
- delete clients[this.id];
- require("./outputs.js").unregisterOutput(this.id);
- this.sock = null;
- }
- });
- this.radios = {};
- var allRadios = require("./config.js").RADIOS;
- for (var i in allRadios)
- this.radios[i] = {
- address: allRadios[i],
- state: false
- };
- this.sendInputStates();
- }
- Client.prototype.onData = function(data) {
- if (data.startsWith("HELO"))
- this.name = data.substr("HELO".length).trim() +" (" +this.sock.remoteAddress +")";
- else if (data.startsWith("STATUS")) {
- data = JSON.parse(data.substr("STATUS".length));
- if (data) {
- this.status.battery = data.battery !== undefined ? data.battery :this.status.battery;
- this.status.plugged = data.plugged !== undefined ? data.plugged :this.status.plugged;
- this.status.volume = data.volume !== undefined ? data.volume :this.status.volume;
- this.status.lastUpdate = Date.now();
- }
- } else if (data.startsWith("PONG")) {
- if (this.ping.pending) {
- const now = Date.now();
- this.ping = {
- lastUpdate: now,
- duration: now -this.ping.pending,
- pending: 0
- };
- this.scheduleNextPing();
- }
- }
- }
- Client.prototype.requestPing = function() {
- if (this.sock) {
- this.ping.pending = Date.now();
- this.sock.write("PING\n");
- }
- }
- Client.prototype.scheduleNextPing = function() {
- setTimeout(() => {this.requestPing();}, 90000); // 1 min 30 sec
- }
- Client.prototype.getName = function() {
- return this.name;
- }
- Client.prototype.kill = function() {
- this.sock.destroy();
- this.active = false;
- }
- Client.prototype.getInputs = function() {
- var result = {};
- for (var i in this.radios)
- result[i] = this.radios[i].state;
- return result;
- }
- Client.prototype.sendInputStates = function() {
- this.sock.write("SET" +JSON.stringify(this.radios) +"\n");
- }
- Client.prototype.setState = function(inputId, state) {
- if (!this.radios[inputId])
- return false;
- if (this.radios[inputId].state !== !!state) {
- this.radios[inputId].state = !!state;
- this.sendInputStates();
- }
- return true;
- }
- Client.prototype.getStatus = function() {
- return {
- status: this.status.lastUpdate ? this.status : undefined,
- ping: this.ping.lastUpdate ? { lastUpdate: this.ping.lastUpdate, duration: this.ping.duration, pending: !!this.ping.pending } : undefined
- };
- }
- Client.prototype.setVolume = function(volume) {
- this.sock.write("SETVOL" +volume +"\n");
- }
- function onClientConnection(sock) {
- var cli = new Client(sock);
- if (clients[cli.id])
- clients[cli.id].kill();
- clients[cli.id] = cli;
- cli.requestPing();
- require("./outputs.js").registerOutput(cli.id, cli);
- }
- module.exports.init = function() {
- net.createServer(onClientConnection).listen(require('./config.js').TCP_PORT, require('./config.js').TCP_LISTEN);
- }
|