-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNetworker.js
More file actions
123 lines (100 loc) · 2.72 KB
/
Networker.js
File metadata and controls
123 lines (100 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
'use strict';
const debug = require('debug')('network');
function Networker(socket, handler) {
this.socket = socket;
this._packet = {};
this._process = false;
this._state = 0;
this._type = 0;
this._payloadLength = 0;
this._bufferedBytes = 0;
this.queue = [];
this.handler = handler;
}
Networker.prototype.init = function () {
this.socket.on('data', (data) => {
this._bufferedBytes += data.length;
this.queue.push(data);
this._process = true;
this._onData();
});
this.socket.on('served', this.handler);
};
Networker.prototype._hasEnough = function (size) {
if (this._bufferedBytes >= size) {
return true;
}
this._process = false;
return false;
}
Networker.prototype._readBytes = function (size) {
let result;
this._bufferedBytes -= size;
if (size === this.queue[0].length) {
return this.queue.shift();
}
if (size < this.queue[0].length) {
result = this.queue[0].slice(0, size);
this.queue[0] = this.queue[0].slice(size);
return result;
}
result = Buffer.allocUnsafe(size);
let offset = 0;
let length;
while (size > 0) {
length = this.queue[0].length;
if (size >= length) {
this.queue[0].copy(result, offset);
offset += length;
this.queue.shift();
} else {
this.queue[0].copy(result, offset, 0, size);
this.queue[0] = this.queue[0].slice(size);
}
size -= length;
}
return result;
}
Networker.prototype._getHeader = function () {
if (this._hasEnough(2)) {
this._payloadLength = this._readBytes(2).readUInt16BE(0, true);
this._state = 1;
}
}
Networker.prototype._getPayload = function () {
if (this._hasEnough(this._payloadLength)) {
let recieved = this._readBytes(this._payloadLength);
this.socket.emit('served', recieved);
this._state = 0;
}
}
Networker.prototype._onData = function (data) {
while (this._process) {
switch (this._state) {
case 0:
this._getHeader();
break;
case 1:
this._getPayload();
break;
}
}
}
Networker.prototype.send = function (message) {
let buffer = Buffer.from(message);
this._header(buffer.length);
this._packet.message = buffer;
this._send();
}
Networker.prototype._header = function (messageLength) {
this._packet.header = { length: messageLength };
};
Networker.prototype._send = function () {
let contentLength = Buffer.allocUnsafe(2);
contentLength.writeUInt16BE(this._packet.header.length);
debug('Attempting to write...', this._packet);
this.socket.write(contentLength);
this.socket.write(this._packet.message);
this._packet = {};
};
module.exports = Networker;