Skip to content

Commit 7c94304

Browse files
committed
feat: Add missing Socket properties
bytesRead, bytesWritten, connecting, destroyed, pending & readyState
1 parent 33b9bf4 commit 7c94304

File tree

2 files changed

+60
-26
lines changed

2 files changed

+60
-26
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,18 @@ Here are listed all methods implemented in `react-native-tcp-socket`, their func
236236
* **Properties:**
237237
* Inherited from [`Stream.Writable`](https://nodejs.org/api/stream.html#stream_class_stream_writable):
238238
* [`writableNeedDrain`](https://nodejs.org/api/stream.html#stream_writable_writableneeddrain)
239+
* [`bytesRead`](https://nodejs.org/api/net.html#socketbytesread)
240+
* [`bytesWritten`](https://nodejs.org/api/net.html#socketbyteswritten)
241+
* [`connecting`](https://nodejs.org/api/net.html#socketconnecting)
242+
* [`destroyed`](https://nodejs.org/api/net.html#socketdestroyed)
243+
* [`localAddress`](https://nodejs.org/api/net.html#net_socket_localaddress)
244+
* [`localPort`](https://nodejs.org/api/net.html#net_socket_localport)
239245
* [`remoteAddress`](https://nodejs.org/api/net.html#net_socket_remoteaddress)
240246
* [`remoteFamily`](https://nodejs.org/api/net.html#net_socket_remotefamily)
241247
* [`remotePort`](https://nodejs.org/api/net.html#net_socket_remoteport)
242-
* [`localAddress`](https://nodejs.org/api/net.html#net_socket_localaddress)
243-
* [`localPort`](https://nodejs.org/api/net.html#net_socket_localport)
248+
* [`pending`](https://nodejs.org/api/net.html#socketpending)
244249
* [`timeout`](https://nodejs.org/api/net.html#sockettimeout)
250+
* [`readyState`](https://nodejs.org/api/net.html#socketreadystate)
245251
* **Events:**
246252
* Inherited from [`Stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable):
247253
* [`'pause'`](https://nodejs.org/api/stream.html#stream_event_pause)

src/Socket.js

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ import { Buffer } from 'buffer';
66
const Sockets = NativeModules.TcpSockets;
77
import { nativeEventEmitter, getNextId } from './Globals';
88

9-
const STATE = {
10-
DISCONNECTED: 0,
11-
CONNECTING: 1,
12-
CONNECTED: 2,
13-
};
14-
159
/**
1610
* @typedef {"ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"} BufferEncoding
1711
*
@@ -64,8 +58,6 @@ export default class Socket extends EventEmitter {
6458
this._timeoutMsecs = 0;
6559
/** @type {number | undefined} @private */
6660
this._timeout = undefined;
67-
/** @type {number} @private */
68-
this._state = STATE.DISCONNECTED;
6961
/** @private */
7062
this._encoding = undefined;
7163
/** @private */
@@ -80,12 +72,24 @@ export default class Socket extends EventEmitter {
8072
this._resuming = false;
8173
/** @private */
8274
this._writeBufferSize = 0;
75+
/** @private */
76+
this._bytesRead = 0;
77+
/** @private */
78+
this._bytesWritten = 0;
79+
/** @private */
80+
this._connecting = false;
81+
/** @private */
82+
this._pending = true;
83+
/** @private */
84+
this._destroyed = false;
85+
// TODO: Add readOnly and writeOnly states
86+
/** @type {'opening' | 'open' | 'readOnly' | 'writeOnly'} @private */
87+
this._readyState = 'open'; // Incorrect, but matches NodeJS behavior
8388
/** @type {{ id: number; data: string; }[]} @private */
8489
this._pausedDataEvents = [];
8590
this.readableHighWaterMark = 16384;
8691
this.writableHighWaterMark = 16384;
8792
this.writableNeedDrain = false;
88-
this.bytesSent = 0;
8993
this.localAddress = undefined;
9094
this.localPort = undefined;
9195
this.remoteAddress = undefined;
@@ -94,6 +98,30 @@ export default class Socket extends EventEmitter {
9498
this._registerEvents();
9599
}
96100

101+
get readyState() {
102+
return this._readyState;
103+
}
104+
105+
get destroyed() {
106+
return this._destroyed;
107+
}
108+
109+
get pending() {
110+
return this._pending;
111+
}
112+
113+
get connecting() {
114+
return this._connecting;
115+
}
116+
117+
get bytesWritten() {
118+
return this._bytesWritten;
119+
}
120+
121+
get bytesRead() {
122+
return this._bytesRead;
123+
}
124+
97125
get timeout() {
98126
return this._timeout;
99127
}
@@ -112,7 +140,9 @@ export default class Socket extends EventEmitter {
112140
* @param {NativeConnectionInfo} connectionInfo
113141
*/
114142
_setConnected(connectionInfo) {
115-
this._state = STATE.CONNECTED;
143+
this._connecting = false;
144+
this._readyState = 'open';
145+
this._pending = false;
116146
this.localAddress = connectionInfo.localAddress;
117147
this.localPort = connectionInfo.localPort;
118148
this.remoteAddress = connectionInfo.remoteAddress;
@@ -141,9 +171,8 @@ export default class Socket extends EventEmitter {
141171
if (customOptions.tlsCert) {
142172
customOptions.tlsCert = Image.resolveAssetSource(customOptions.tlsCert).uri;
143173
}
144-
// console.log(getAndroidResourceIdentifier(customOptions.tlsCert));
145-
this._state = STATE.CONNECTING;
146-
this._destroyed = false;
174+
this._connecting = true;
175+
this._readyState = 'opening';
147176
Sockets.connect(this._id, customOptions.host, customOptions.port, customOptions);
148177
return this;
149178
}
@@ -218,7 +247,7 @@ export default class Socket extends EventEmitter {
218247
* @param {boolean} noDelay Default: `true`
219248
*/
220249
setNoDelay(noDelay = true) {
221-
if (this._state != STATE.CONNECTED) {
250+
if (this._pending) {
222251
this.once('connect', () => this.setNoDelay(noDelay));
223252
return this;
224253
}
@@ -235,7 +264,7 @@ export default class Socket extends EventEmitter {
235264
* @param {number} initialDelay ***IGNORED**. Default: `0`
236265
*/
237266
setKeepAlive(enable = false, initialDelay = 0) {
238-
if (this._state != STATE.CONNECTED) {
267+
if (this._pending) {
239268
this.once('connect', () => this.setKeepAlive(enable, initialDelay));
240269
return this;
241270
}
@@ -266,17 +295,15 @@ export default class Socket extends EventEmitter {
266295
* @param {BufferEncoding} [encoding]
267296
*/
268297
end(data, encoding) {
269-
if (this._destroyed) return;
270298
if (data) {
271299
this.write(data, encoding, () => {
272-
this._destroyed = true;
273300
Sockets.end(this._id);
274301
});
275302
} else {
276-
this._destroyed = true;
277303
this._clearTimeout();
278304
Sockets.end(this._id);
279305
}
306+
return this;
280307
}
281308

282309
destroy() {
@@ -285,6 +312,7 @@ export default class Socket extends EventEmitter {
285312
this._clearTimeout();
286313
Sockets.destroy(this._id);
287314
}
315+
return this;
288316
}
289317

290318
/**
@@ -303,7 +331,7 @@ export default class Socket extends EventEmitter {
303331
*/
304332
write(buffer, encoding, cb) {
305333
const self = this;
306-
if (this._state === STATE.DISCONNECTED) throw new Error('Socket is not connected.');
334+
if (this._pending || this._destroyed) throw new Error('Socket is not connected.');
307335

308336
const generatedBuffer = this._generateSendBuffer(buffer, encoding);
309337
this._writeBufferSize += generatedBuffer.byteLength;
@@ -316,7 +344,7 @@ export default class Socket extends EventEmitter {
316344
this._writeBufferSize -= generatedBuffer.byteLength;
317345
this._lastRcvMsgId = msgId;
318346
if (self._timeout) self._activateTimer();
319-
if (this.writableNeedDrain && this._lastSentMsgId == msgId) {
347+
if (this.writableNeedDrain && this._lastSentMsgId === msgId) {
320348
this.writableNeedDrain = false;
321349
this.emit('drain');
322350
}
@@ -331,6 +359,7 @@ export default class Socket extends EventEmitter {
331359
const ok = this._writeBufferSize < this.writableHighWaterMark;
332360
if (!ok) this.writableNeedDrain = true;
333361
this._lastSentMsgId = currentMsgId;
362+
this._bytesWritten += generatedBuffer.byteLength;
334363
Sockets.write(this._id, generatedBuffer.toString('base64'), currentMsgId);
335364
return ok;
336365
}
@@ -409,8 +438,9 @@ export default class Socket extends EventEmitter {
409438
_onDeviceDataEvt = (/** @type {{ id: number; data: string; }} */ evt) => {
410439
if (evt.id !== this._id) return;
411440
if (!this._paused) {
412-
const bufferTest = Buffer.from(evt.data, 'base64');
413-
const finalData = this._encoding ? bufferTest.toString(this._encoding) : bufferTest;
441+
const bufferData = Buffer.from(evt.data, 'base64');
442+
this._bytesRead += bufferData.byteLength;
443+
const finalData = this._encoding ? bufferData.toString(this._encoding) : bufferData;
414444
this.emit('data', finalData);
415445
} else {
416446
// If the socket is paused, save the data events for later
@@ -479,8 +509,6 @@ export default class Socket extends EventEmitter {
479509
* @private
480510
*/
481511
_setDisconnected() {
482-
if (this._state === STATE.DISCONNECTED) return;
483512
this._unregisterEvents();
484-
this._state = STATE.DISCONNECTED;
485513
}
486514
}

0 commit comments

Comments
 (0)