Skip to content

Commit 338a9f7

Browse files
author
Neal Manaktola
committed
expose flush on RCTWebSocketModule to close all open websockets synchronously
add log statement back
1 parent a3f807f commit 338a9f7

4 files changed

Lines changed: 96 additions & 37 deletions

File tree

Libraries/WebSocket/RCTSRWebSocket.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ extern NSString *const RCTSRHTTPResponseErrorKey;
8080
- (void)open;
8181

8282
- (void)close;
83+
- (void)closeSync;
84+
8385
- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason;
8486

8587
// Send a UTF8 String or Data.

Libraries/WebSocket/RCTSRWebSocket.m

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -554,48 +554,65 @@ - (void)close
554554
[self closeWithCode:RCTSRStatusCodeNormal reason:nil];
555555
}
556556

557+
- (void)closeSync
558+
{
559+
[self closeWithCode:RCTSRStatusCodeNormal reason:nil isBlocking:YES];
560+
}
561+
557562
- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason
558563
{
559-
assert(code);
560-
dispatch_async(_workQueue, ^{
561-
if (self.readyState == RCTSR_CLOSING || self.readyState == RCTSR_CLOSED) {
562-
return;
563-
}
564+
[self closeWithCode:code reason:reason isBlocking:NO];
565+
}
564566

565-
BOOL wasConnecting = self.readyState == RCTSR_CONNECTING;
567+
- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason isBlocking:(BOOL)isBlocking
568+
{
569+
assert(code);
570+
571+
void (^performClose)(void) = ^{
572+
if (self.readyState == RCTSR_CLOSING || self.readyState == RCTSR_CLOSED) {
573+
return;
574+
}
566575

567-
self.readyState = RCTSR_CLOSING;
576+
BOOL wasConnecting = self.readyState == RCTSR_CONNECTING;
568577

569-
RCTSRLog(@"Closing with code %ld reason %@", code, reason);
578+
self.readyState = RCTSR_CLOSING;
570579

571-
if (wasConnecting) {
572-
[self _disconnect];
573-
return;
574-
}
580+
RCTSRLog(@"Closing with code %ld reason %@", code, reason);
581+
582+
if (wasConnecting) {
583+
[self _disconnect:isBlocking];
584+
return;
585+
}
575586

576-
size_t maxMsgSize = [reason maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding];
577-
NSMutableData *mutablePayload = [[NSMutableData alloc] initWithLength:sizeof(uint16_t) + maxMsgSize];
578-
NSData *payload = mutablePayload;
587+
size_t maxMsgSize = [reason maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding];
588+
NSMutableData *mutablePayload = [[NSMutableData alloc] initWithLength:sizeof(uint16_t) + maxMsgSize];
589+
NSData *payload = mutablePayload;
579590

580-
((uint16_t *)mutablePayload.mutableBytes)[0] = NSSwapBigShortToHost(code);
591+
((uint16_t *)mutablePayload.mutableBytes)[0] = NSSwapBigShortToHost(code);
581592

582-
if (reason) {
583-
NSRange remainingRange = {0};
593+
if (reason) {
594+
NSRange remainingRange = {0};
584595

585-
NSUInteger usedLength = 0;
596+
NSUInteger usedLength = 0;
586597

587-
BOOL success __unused = [reason getBytes:(char *)mutablePayload.mutableBytes + sizeof(uint16_t) maxLength:payload.length - sizeof(uint16_t) usedLength:&usedLength encoding:NSUTF8StringEncoding options:NSStringEncodingConversionExternalRepresentation range:NSMakeRange(0, reason.length) remainingRange:&remainingRange];
598+
BOOL success __unused = [reason getBytes:(char *)mutablePayload.mutableBytes + sizeof(uint16_t) maxLength:payload.length - sizeof(uint16_t) usedLength:&usedLength encoding:NSUTF8StringEncoding options:NSStringEncodingConversionExternalRepresentation range:NSMakeRange(0, reason.length) remainingRange:&remainingRange];
588599

589-
assert(success);
590-
assert(remainingRange.length == 0);
600+
assert(success);
601+
assert(remainingRange.length == 0);
591602

592-
if (usedLength != maxMsgSize) {
593-
payload = [payload subdataWithRange:NSMakeRange(0, usedLength + sizeof(uint16_t))];
603+
if (usedLength != maxMsgSize) {
604+
payload = [payload subdataWithRange:NSMakeRange(0, usedLength + sizeof(uint16_t))];
605+
}
594606
}
595-
}
596607

597-
[self _sendFrameWithOpcode:RCTSROpCodeConnectionClose data:payload];
598-
});
608+
[self _sendFrameWithOpcode:RCTSROpCodeConnectionClose data:payload skipWorkQueueAssertion:isBlocking];
609+
};
610+
611+
if (isBlocking) {
612+
performClose();
613+
} else {
614+
dispatch_async(_workQueue, performClose);
615+
}
599616
}
600617

601618
- (void)_closeWithProtocolError:(NSString *)message
@@ -630,15 +647,22 @@ - (void)_failWithError:(NSError *)error
630647
});
631648
}
632649

633-
- (void)_writeData:(NSData *)data
650+
- (void)_writeData:(NSData *)data skipWorkQueueAssertion:(BOOL)skipWorkQueueAssertion
634651
{
635-
[self assertOnWorkQueue];
652+
if (skipWorkQueueAssertion == NO){
653+
[self assertOnWorkQueue];
654+
}
636655

637656
if (_closeWhenFinishedWriting) {
638657
return;
639658
}
640659
[_outputBuffer appendData:data];
641-
[self _pumpWriting];
660+
[self _pumpWriting:skipWorkQueueAssertion];
661+
}
662+
663+
- (void)_writeData:(NSData *)data
664+
{
665+
[self _writeData:data skipWorkQueueAssertion:NO];
642666
}
643667

644668
- (void)send:(id)data
@@ -772,14 +796,22 @@ - (void)handleCloseWithData:(NSData *)data
772796
});
773797
}
774798

775-
- (void)_disconnect
799+
- (void)_disconnect:(BOOL)skipWorkQueueAssertion
776800
{
777-
[self assertOnWorkQueue];
801+
if (skipWorkQueueAssertion == NO) {
802+
[self assertOnWorkQueue];
803+
}
804+
778805
RCTSRLog(@"Trying to disconnect");
779806
_closeWhenFinishedWriting = YES;
780807
[self _pumpWriting];
781808
}
782809

810+
- (void)_disconnect
811+
{
812+
[self _disconnect:NO];
813+
}
814+
783815
- (void)_handleFrameWithData:(NSData *)frameData opCode:(NSInteger)opcode
784816
{
785817
// Check that the current data is valid UTF8
@@ -1005,9 +1037,14 @@ - (void)_readFrameNew
10051037
});
10061038
}
10071039

1008-
- (void)_pumpWriting
1040+
- (void)_pumpWriting {
1041+
[self _pumpWriting:NO];
1042+
}
1043+
- (void)_pumpWriting:(BOOL)skipWorkQueueAssertion
10091044
{
1010-
[self assertOnWorkQueue];
1045+
if (skipWorkQueueAssertion == NO) {
1046+
[self assertOnWorkQueue];
1047+
}
10111048

10121049
NSUInteger dataLength = _outputBuffer.length;
10131050
if (dataLength - _outputBufferOffset > 0 && _outputStream.hasSpaceAvailable) {
@@ -1223,9 +1260,16 @@ - (void)_pumpScanner
12231260

12241261
static const size_t RCTSRFrameHeaderOverhead = 32;
12251262

1226-
- (void)_sendFrameWithOpcode:(RCTSROpCode)opcode data:(NSData *)data
1263+
- (void)_sendFrameWithOpcode:(RCTSROpCode)opcode data:(NSData *)data {
1264+
[self _sendFrameWithOpcode:opcode data:data skipWorkQueueAssertion:NO];
1265+
}
1266+
1267+
1268+
- (void)_sendFrameWithOpcode:(RCTSROpCode)opcode data:(NSData *)data skipWorkQueueAssertion:(BOOL)skipWorkQueueAssertion
12271269
{
1228-
[self assertOnWorkQueue];
1270+
if (skipWorkQueueAssertion == NO) {
1271+
[self assertOnWorkQueue];
1272+
}
12291273

12301274
if (nil == data) {
12311275
return;
@@ -1290,7 +1334,7 @@ - (void)_sendFrameWithOpcode:(RCTSROpCode)opcode data:(NSData *)data
12901334
assert(frame_buffer_size <= [frame length]);
12911335
frame.length = frame_buffer_size;
12921336

1293-
[self _writeData:frame];
1337+
[self _writeData:frame skipWorkQueueAssertion:skipWorkQueueAssertion];
12941338
}
12951339

12961340
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode

React/CoreModules/RCTWebSocketModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ NS_ASSUME_NONNULL_BEGIN
2424

2525
- (void)sendData:(NSData *)data forSocketID:(nonnull NSNumber *)socketID;
2626

27+
// Closes all open websockets on the main thread
28+
- (void)flush;
29+
2730
@end
2831

2932
@interface RCTBridge (RCTWebSocketModule)

React/CoreModules/RCTWebSocketModule.mm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ - (NSArray *)supportedEvents
5151
return @[ @"websocketMessage", @"websocketOpen", @"websocketFailed", @"websocketClosed" ];
5252
}
5353

54+
55+
- (void)flush
56+
{
57+
_contentHandlers = nil;
58+
for (RCTSRWebSocket *socket in _sockets.allValues) {
59+
socket.delegate = nil;
60+
[socket closeSync];
61+
}
62+
}
63+
5464
- (void)invalidate
5565
{
5666
[super invalidate];

0 commit comments

Comments
 (0)