Skip to content

Commit 6b19987

Browse files
feat: implement allowHalfOpen and end event for libp2p compatibility
1 parent 4c6d55e commit 6b19987

File tree

7 files changed

+34
-5
lines changed

7 files changed

+34
-5
lines changed

android/src/main/java/com/asterinet/react/tcpsocket/TcpEventListener.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ public void onClose(int id, Exception e) {
117117
sendEvent("close", eventParams);
118118
}
119119

120+
public void onEnd(int id) {
121+
WritableMap eventParams = Arguments.createMap();
122+
eventParams.putInt("id", id);
123+
sendEvent("end", eventParams);
124+
}
125+
120126
public void onError(int id, Exception e) {
121127
Log.e(TcpSocketModule.TAG, "Exception on socket " + id, e);
122128
String error = e.getMessage();

android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ public void run() {
255255
if (bufferCount > 0) {
256256
receiverListener.onData(socketId, Arrays.copyOfRange(buffer, 0, bufferCount));
257257
} else if (bufferCount == -1) {
258-
clientSocket.destroy();
258+
receiverListener.onEnd(socketId);
259+
break;
259260
}
260261
}
261262
} catch (IOException | InterruptedException ioe) {

ios/TcpSocketClient.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef enum RCTTCPError RCTTCPError;
4343
- (void)onClose:(TcpSocketClient *)client withError:(NSError *)err;
4444
- (void)onError:(TcpSocketClient *)client withError:(NSError *)err;
4545
- (void)onWrittenData:(TcpSocketClient *)client msgId:(NSNumber *)msgId;
46+
- (void)onEnd:(NSNumber *)clientID;
4647
- (NSNumber *)getNextId;
4748

4849
@end

ios/TcpSocketClient.m

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,8 @@ - (void)socket:(GCDAsyncSocket *)sock
579579
}
580580

581581
- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock {
582-
// TODO : investigate for half-closed sockets
583-
// for now close the stream completely
584-
[sock disconnect];
582+
// Half-closed socket support
583+
[_clientDelegate onEnd:_id];
585584
}
586585

587586
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {

ios/TcpSockets.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ @implementation TcpSockets {
2222
- (NSArray<NSString *> *)supportedEvents {
2323
return @[
2424
@"connect", @"listening", @"connection", @"secureConnection", @"data",
25-
@"close", @"error", @"written"
25+
@"close", @"error", @"written", @"end"
2626
];
2727
}
2828

@@ -217,6 +217,13 @@ - (void)onWrittenData:(TcpSocketClient *)client msgId:(NSNumber *)msgId {
217217
}];
218218
}
219219

220+
- (void)onEnd:(NSNumber *)clientID {
221+
[self sendEventWithName:@"end"
222+
body:@{
223+
@"id" : clientID
224+
}];
225+
}
226+
220227
- (void)onConnect:(TcpSocketClient *)client {
221228
GCDAsyncSocket *socket = [client getSocket];
222229
[self sendEventWithName:@"connect"

src/Server.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ export default class Server extends EventEmitter {
249249
const keepAliveDelay = this._serverOptions.keepAliveInitialDelay || 0;
250250
newSocket.setKeepAlive(this._serverOptions.keepAlive, keepAliveDelay);
251251
}
252+
253+
if (this._serverOptions.allowHalfOpen !== undefined) {
254+
newSocket.allowHalfOpen = this._serverOptions.allowHalfOpen;
255+
}
252256
}
253257

254258
return newSocket;

src/Socket.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export default class Socket extends EventEmitter {
9595
this.remoteAddress = undefined;
9696
this.remotePort = undefined;
9797
this.remoteFamily = undefined;
98+
this.allowHalfOpen = false; // Default per Node.js spec
9899
this._registerEvents();
99100
}
100101

@@ -457,6 +458,15 @@ export default class Socket extends EventEmitter {
457458
this.destroy();
458459
this.emit('error', evt.error);
459460
});
461+
this._endListener = this._eventEmitter.addListener('end', (evt) => {
462+
if (evt.id !== this._id) return;
463+
this._readyState = 'readOnly'; // Can still write but not read
464+
this.emit('end');
465+
// If allowHalfOpen is false, auto-close the writable side
466+
if (!this.allowHalfOpen) {
467+
this.end();
468+
}
469+
});
460470
this._closeListener = this._eventEmitter.addListener('close', (evt) => {
461471
if (evt.id !== this._id) return;
462472
this._setDisconnected();
@@ -479,6 +489,7 @@ export default class Socket extends EventEmitter {
479489
_unregisterEvents() {
480490
this._dataListener?.remove();
481491
this._errorListener?.remove();
492+
this._endListener?.remove();
482493
this._closeListener?.remove();
483494
this._connectListener?.remove();
484495
this._writtenListener?.remove();

0 commit comments

Comments
 (0)