From 63886dc4ab6caa62762008f8d7b6dea977e12ac0 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Sun, 14 Jun 2020 13:05:42 +0200 Subject: [PATCH 1/5] Add JS part --- src/TcpSocket.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/TcpSocket.js b/src/TcpSocket.js index a08f818..0c1570b 100644 --- a/src/TcpSocket.js +++ b/src/TcpSocket.js @@ -204,6 +204,19 @@ export default class TcpSocket { return this; } + /** + * Enable/disable the use of Nagle's algorithm. When a TCP connection is created, it will have Nagle's algorithm enabled. + * + * Nagle's algorithm delays data before it is sent via the network. It attempts to optimize throughput at the expense of latency. + * + * Passing `true` for `noDelay` or not passing an argument will disable Nagle's algorithm for the socket. Passing false for noDelay will enable Nagle's algorithm. + * + * @param {boolean} noDelay + */ + setNoDelay(noDelay = true) { + Sockets.setNoDelay(this._id, noDelay); + } + address() { return this._address; } From 0df0bf09af266f2f0d4eba442bf0f16aa5a9dd6e Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Sun, 14 Jun 2020 13:24:26 +0200 Subject: [PATCH 2/5] Add Android implementation --- .../asterinet/react/tcpsocket/TcpSocketClient.java | 10 ++++++++++ .../asterinet/react/tcpsocket/TcpSocketModule.java | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java index 5474bdb..371e974 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java @@ -131,4 +131,14 @@ public void close() { mReceiverListener.onClose(getId(), e.getMessage()); } } + + /** + * @param noDelay `true` will disable Nagle's algorithm for the socket (enable TCP_NODELAY) + */ + public void setNoDelay(final boolean noDelay) throws IOException { + if (socket == null) { + throw new IOException("Socket is not connected."); + } + socket.setTcpNoDelay(noDelay); + } } diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java index b6f6fae..a8c437b 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java @@ -164,6 +164,20 @@ protected void doInBackgroundGuarded(Void... params) { }.executeOnExecutor(executorService); } + @ReactMethod + public void setNoDelay(@NonNull final Integer cId, final boolean noDelay) { + final TcpSocketClient client = socketClients.get(cId); + if (client == null) { + onError(cId, TAG + "socket not found."); + return; + } + try { + client.setNoDelay(noDelay); + } catch (IOException e) { + onError(cId, e.getMessage()); + } + } + private void requestNetwork(final int transportType) throws InterruptedException { final NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder(); requestBuilder.addTransportType(transportType); From f7553f9aa03fe0aac98ac4a64dffbfe867aa5a21 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Sun, 14 Jun 2020 15:12:39 +0200 Subject: [PATCH 3/5] Add iOS implementation --- ios/TcpSocketClient.h | 1 + ios/TcpSocketClient.m | 13 +++++++++++++ ios/TcpSockets.m | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/ios/TcpSocketClient.h b/ios/TcpSocketClient.h index 5706f0b..3224386 100644 --- a/ios/TcpSocketClient.h +++ b/ios/TcpSocketClient.h @@ -92,5 +92,6 @@ typedef enum RCTTCPError RCTTCPError; */ - (void)destroy; +- (void)setNoDelay:(bool)noDelay; @end diff --git a/ios/TcpSocketClient.m b/ios/TcpSocketClient.m index 4df8096..a18ade9 100644 --- a/ios/TcpSocketClient.m +++ b/ios/TcpSocketClient.m @@ -1,4 +1,5 @@ #import +#import #import #import "TcpSocketClient.h" @@ -124,6 +125,18 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti @"family": @"unkown" }; } +- (void)setNoDelay:(bool)noDelay +{ + [_tcpSocket performBlock:^{ + int fd = [self->_tcpSocket socketFD]; + int on = noDelay; + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)) == -1) { + /* TODO: handle error */ + RCTLogWarn(@"setNoDelay caused an unexpected error"); + } + }]; +} + - (BOOL)listen:(NSDictionary *)options error:(NSError **)error { if (_tcpSocket) { diff --git a/ios/TcpSockets.m b/ios/TcpSockets.m index 81473cb..b988e62 100644 --- a/ios/TcpSockets.m +++ b/ios/TcpSockets.m @@ -116,6 +116,13 @@ - (TcpSocketClient *)createSocket:(nonnull NSNumber*)cId } } +RCT_EXPORT_METHOD(setNoDelay:(nonnull NSNumber*)cId noDelay:(bool)noDelay) { + TcpSocketClient* client = [self findClient:cId]; + if (!client) return; + + [client setNoDelay:noDelay]; +} + - (void)onConnect:(TcpSocketClient*) client { [self sendEventWithName:@"connect" From 65c08c8983f13f1414a326b822d7c44c2f25c319 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Sun, 14 Jun 2020 15:32:11 +0200 Subject: [PATCH 4/5] fix iOS implementation --- ios/TcpSocketClient.h | 2 +- ios/TcpSocketClient.m | 4 ++-- ios/TcpSockets.m | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/TcpSocketClient.h b/ios/TcpSocketClient.h index 3224386..672ee89 100644 --- a/ios/TcpSocketClient.h +++ b/ios/TcpSocketClient.h @@ -92,6 +92,6 @@ typedef enum RCTTCPError RCTTCPError; */ - (void)destroy; -- (void)setNoDelay:(bool)noDelay; +- (void)setNoDelay:(BOOL)noDelay; @end diff --git a/ios/TcpSocketClient.m b/ios/TcpSocketClient.m index a18ade9..a6105f2 100644 --- a/ios/TcpSocketClient.m +++ b/ios/TcpSocketClient.m @@ -125,11 +125,11 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti @"family": @"unkown" }; } -- (void)setNoDelay:(bool)noDelay +- (void)setNoDelay:(BOOL)noDelay { [_tcpSocket performBlock:^{ int fd = [self->_tcpSocket socketFD]; - int on = noDelay; + int on = noDelay ? 1 : 0; if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)) == -1) { /* TODO: handle error */ RCTLogWarn(@"setNoDelay caused an unexpected error"); diff --git a/ios/TcpSockets.m b/ios/TcpSockets.m index b988e62..166ea54 100644 --- a/ios/TcpSockets.m +++ b/ios/TcpSockets.m @@ -116,7 +116,7 @@ - (TcpSocketClient *)createSocket:(nonnull NSNumber*)cId } } -RCT_EXPORT_METHOD(setNoDelay:(nonnull NSNumber*)cId noDelay:(bool)noDelay) { +RCT_EXPORT_METHOD(setNoDelay:(nonnull NSNumber*)cId noDelay:(BOOL)noDelay) { TcpSocketClient* client = [self findClient:cId]; if (!client) return; From b0935df3ed3246be56ff35c99582c61085e80d95 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Sun, 14 Jun 2020 17:16:58 +0200 Subject: [PATCH 5/5] Add documentation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cd6ea10..2f31e04 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ _Note: In order to use self-signed certificates make sure to [update your metro. * [`createConnection(options[, callback])`](#createconnection) * [`write(data[, encoding][, callback])`](#write) * [`destroy()`](#destroy) + * [`setNoDelay([noDelay])`](https://nodejs.org/api/net.html#net_socket_setnodelay_nodelay) #### `createConnection()` `createConnection(options[, callback])` creates a TCP connection using the given [`options`](#createconnection-options).