88 lines
2.6 KiB
Plaintext
88 lines
2.6 KiB
Plaintext
'use strict';
|
|
|
|
const stream = require('stream'),
|
|
Socket = require('net').Socket,
|
|
assert = require('assert');
|
|
|
|
/**
|
|
* Base TCPDevice class for handling TCP socket from tracking device
|
|
*
|
|
*/
|
|
class TCPDevice extends stream.Duplex {
|
|
|
|
constructor(socket, ops) {
|
|
super(ops);
|
|
|
|
this.ops = Object.assign({}, {
|
|
maxInvalidReadTry: 5
|
|
}, ops);
|
|
|
|
// Perform type assertions
|
|
assert.ok(socket instanceof Socket, 'socket argument must be an instance of Socket'); // prettier-ignore
|
|
|
|
this.id = null;
|
|
this.msgReceived = 0;
|
|
this._invalidTry = 0;
|
|
|
|
this._socket = socket;
|
|
this._socket.on('close', hadError => this.emit('close', hadError));
|
|
// this._socket.on("connect", () => console.log("Client connected !"));
|
|
this._socket.on('drain', () => this.emit('drain'));
|
|
this._socket.on('end', () => this.emit('end'));
|
|
this._socket.on('error', err => this.emit('error', err));
|
|
this._socket.on('lookup', (e, a, f, h) => this.emit('lookup', e, a, f, h));
|
|
this._socket.on('readable', this._onData.bind(this));
|
|
this._socket.on('timeout', () => this.emit('timeout'));
|
|
}
|
|
|
|
/**
|
|
* Half-closes the socket. It is still possible that the opposite
|
|
* side is still sending data.
|
|
*/
|
|
end() {
|
|
this._socket.end();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Destroys the socket and ensures that no more I/O activity happens
|
|
* on the socket. When an `err` is included, an 'error' event will
|
|
* be emitted and all listeners will receive the error as an
|
|
* argument.
|
|
* @param err optional error to send
|
|
*/
|
|
destroy(err) {
|
|
this._socket.destroy(err);
|
|
return this;
|
|
}
|
|
|
|
_guardInvalidTries() {
|
|
this._invalidTry++;
|
|
if (this._invalidTry > this.ops.maxInvalidReadTry)
|
|
throw new Error('Reached maximum invalid read try');
|
|
}
|
|
|
|
/**
|
|
* _onData is triggered by the "readable" event on the underlying TCP socket.
|
|
* It is called each time there is new data * received. It is responsible for reading data from the socket and *
|
|
* performing the appropriate action given the current read state.
|
|
* @virtual Extenders implementation must override this menthod acccording to the detail of the protocol
|
|
*/
|
|
_onData() { }
|
|
|
|
_read() {
|
|
|
|
// Trigger a read but wait until the end of the event loop.
|
|
// This is necessary when reading in paused mode where
|
|
// _read was triggered by stream.read() originating inside
|
|
// a "readable" event handler. Attempting to push more data
|
|
// synchronously will not trigger another "readable" event.
|
|
setImmediate(() => this._onData());
|
|
}
|
|
|
|
_write() { }
|
|
_final() { }
|
|
|
|
}
|
|
|
|
module.exports = TCPDevice; |