Skip to content

Commit

Permalink
Make RCTWebSocketModule TurboModule-compatible
Browse files Browse the repository at this point in the history
Summary:
Changelog:
[iOS][Added] - Make RCTWebSocketModule TurboModule-compatible

Reviewed By: PeteTheHeat

Differential Revision: D18353766

fbshipit-source-id: fde0f6593dd203ab3dcb8f9cf40012ba4761d6ba
  • Loading branch information
RSNara authored and facebook-github-bot committed Nov 8, 2019
1 parent 1b2992e commit d73ae1b
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2613,12 +2613,6 @@ + (RCTManagedPointer *)JS_NativeStatusBarManagerIOS_SpecGetHeightCallbackResult:

} // namespace react
} // namespace facebook
@implementation RCTCxxConvert (NativeWebSocketModule_SpecConnectOptionsHeaders)
+ (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptionsHeaders:(id)json
{
return facebook::react::managedPointer<JS::NativeWebSocketModule::SpecConnectOptionsHeaders>(json);
}
@end
@implementation RCTCxxConvert (NativeWebSocketModule_SpecConnectOptions)
+ (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptions:(id)json
{
Expand All @@ -2634,11 +2628,11 @@ + (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptions:(id)json
}

static facebook::jsi::Value __hostFunction_NativeWebSocketModuleSpecJSI_send(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "send", @selector(send:socketID:), args, count);
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "send", @selector(send:forSocketID:), args, count);
}

static facebook::jsi::Value __hostFunction_NativeWebSocketModuleSpecJSI_sendBinary(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "sendBinary", @selector(sendBinary:socketID:), args, count);
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, VoidKind, "sendBinary", @selector(sendBinary:forSocketID:), args, count);
}

static facebook::jsi::Value __hostFunction_NativeWebSocketModuleSpecJSI_ping(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
Expand Down
31 changes: 5 additions & 26 deletions Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -2697,26 +2697,10 @@ namespace facebook {
} // namespace react
} // namespace facebook

namespace JS {
namespace NativeWebSocketModule {
struct SpecConnectOptionsHeaders {
NSString *origin() const;

SpecConnectOptionsHeaders(NSDictionary *const v) : _v(v) {}
private:
NSDictionary *_v;
};
}
}

@interface RCTCxxConvert (NativeWebSocketModule_SpecConnectOptionsHeaders)
+ (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptionsHeaders:(id)json;
@end

namespace JS {
namespace NativeWebSocketModule {
struct SpecConnectOptions {
folly::Optional<JS::NativeWebSocketModule::SpecConnectOptionsHeaders> headers() const;
id<NSObject> _Nullable headers() const;

SpecConnectOptions(NSDictionary *const v) : _v(v) {}
private:
Expand All @@ -2735,9 +2719,9 @@ namespace JS {
options:(JS::NativeWebSocketModule::SpecConnectOptions &)options
socketID:(double)socketID;
- (void)send:(NSString *)message
socketID:(double)socketID;
forSocketID:(double)forSocketID;
- (void)sendBinary:(NSString *)base64String
socketID:(double)socketID;
forSocketID:(double)forSocketID;
- (void)ping:(double)socketID;
- (void)close:(double)code
reason:(NSString *)reason
Expand Down Expand Up @@ -3738,13 +3722,8 @@ inline JS::NativeUIManager::Constants::Builder::Builder(const Input i) : _factor
inline JS::NativeUIManager::Constants::Builder::Builder(Constants i) : _factory(^{
return i.unsafeRawValue();
}) {}
inline NSString *JS::NativeWebSocketModule::SpecConnectOptionsHeaders::origin() const
{
id const p = _v[@"origin"];
return RCTBridgingToString(p);
}
inline folly::Optional<JS::NativeWebSocketModule::SpecConnectOptionsHeaders> JS::NativeWebSocketModule::SpecConnectOptions::headers() const
inline id<NSObject> _Nullable JS::NativeWebSocketModule::SpecConnectOptions::headers() const
{
id const p = _v[@"headers"];
return (p == nil ? folly::none : folly::make_optional(JS::NativeWebSocketModule::SpecConnectOptionsHeaders(p)));
return p;
}
8 changes: 4 additions & 4 deletions Libraries/WebSocket/NativeWebSocketModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @flow
* @format
*/

Expand All @@ -17,11 +17,11 @@ export interface Spec extends TurboModule {
+connect: (
url: string,
protocols: ?Array<string>,
options: ?{headers?: {origin?: string}},
options: {|headers?: Object|},
socketID: number,
) => void;
+send: (message: string, socketID: number) => void;
+sendBinary: (base64String: string, socketID: number) => void;
+send: (message: string, forSocketID: number) => void;
+sendBinary: (base64String: string, forSocketID: number) => void;
+ping: (socketID: number) => void;
+close: (code: number, reason: string, socketID: number) => void;

Expand Down
6 changes: 6 additions & 0 deletions React/CoreModules/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ rn_apple_library(
) + react_module_plugin_providers(
name = "TVNavigationEventEmitter",
native_class_func = "RCTTVNavigationEventEmitterCls",
) + react_module_plugin_providers(
name = "WebSocketExecutor",
native_class_func = "RCTWebSocketExecutorCls",
) + react_module_plugin_providers(
name = "WebSocketModule",
native_class_func = "RCTWebSocketModuleCls",
),
plugins_header = "FBCoreModulesPlugins.h",
preprocessor_flags = OBJC_ARC_PREPROCESSOR_FLAGS + get_debug_preprocessor_flags() + rn_extra_build_flags() + [
Expand Down
2 changes: 2 additions & 0 deletions React/CoreModules/CoreModulesPlugins.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Class RCTDevMenuCls(void) __attribute__((used));
Class RCTDevSettingsCls(void) __attribute__((used));
Class RCTRedBoxCls(void) __attribute__((used));
Class RCTTVNavigationEventEmitterCls(void) __attribute__((used));
Class RCTWebSocketExecutorCls(void) __attribute__((used));
Class RCTWebSocketModuleCls(void) __attribute__((used));

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions React/CoreModules/CoreModulesPlugins.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Class RCTCoreModulesClassProvider(const char *name) {
{"DevSettings", RCTDevSettingsCls},
{"RedBox", RCTRedBoxCls},
{"TVNavigationEventEmitter", RCTTVNavigationEventEmitterCls},
{"WebSocketExecutor", RCTWebSocketExecutorCls},
{"WebSocketModule", RCTWebSocketModuleCls},
};

auto p = sCoreModuleClassMap.find(name);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>

#import <React/RCTSRWebSocket.h>

#import <ReactCommon/RCTTurboModule.h>

#import "CoreModulesPlugins.h"

#if RCT_DEV // Debug executors are only supported in dev mode

typedef void (^RCTWSMessageCallback)(NSError *error, NSDictionary<NSString *, id> *reply);

@interface RCTWebSocketExecutor () <RCTSRWebSocketDelegate>
@interface RCTWebSocketExecutor () <RCTSRWebSocketDelegate, RCTTurboModule>

@end

Expand Down Expand Up @@ -271,3 +274,11 @@ - (void)dealloc
@end

#endif

Class RCTWebSocketExecutorCls(void) {
#if RCT_DEV
return RCTWebSocketExecutor.class;
#else
return nil;
#endif
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

#import <objc/runtime.h>

#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/RCTConvert.h>
#import <React/RCTUtils.h>

#import <React/RCTSRWebSocket.h>

#import "CoreModulesPlugins.h"

@implementation RCTSRWebSocket (React)

- (NSNumber *)reactTag
Expand All @@ -28,7 +30,7 @@ - (void)setReactTag:(NSNumber *)reactTag

@end

@interface RCTWebSocketModule () <RCTSRWebSocketDelegate>
@interface RCTWebSocketModule () <RCTSRWebSocketDelegate, NativeWebSocketModuleSpec>

@end

Expand Down Expand Up @@ -62,7 +64,7 @@ - (void)invalidate
}
}

RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols options:(NSDictionary *)options socketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(connect:(NSURL *)URL protocols:(NSArray *)protocols options:(JS::NativeWebSocketModule::SpecConnectOptions &)options socketID:(double)socketID)
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];

Expand All @@ -79,45 +81,48 @@ - (void)invalidate
request.allHTTPHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];

// Load supplied headers
[options[@"headers"] enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
[request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key];
}];
if ([options.headers() isKindOfClass:NSDictionary.class]) {
NSDictionary *headers = (NSDictionary *)options.headers();
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) {
[request addValue:[RCTConvert NSString:value] forHTTPHeaderField:key];
}];
}

RCTSRWebSocket *webSocket = [[RCTSRWebSocket alloc] initWithURLRequest:request protocols:protocols];
[webSocket setDelegateDispatchQueue:[self methodQueue]];
webSocket.delegate = self;
webSocket.reactTag = socketID;
webSocket.reactTag = @(socketID);
if (!_sockets) {
_sockets = [NSMutableDictionary new];
}
_sockets[socketID] = webSocket;
_sockets[@(socketID)] = webSocket;
[webSocket open];
}

RCT_EXPORT_METHOD(send:(NSString *)message forSocketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(send:(NSString *)message forSocketID:(double)socketID)
{
[_sockets[socketID] send:message];
[_sockets[@(socketID)] send:message];
}

RCT_EXPORT_METHOD(sendBinary:(NSString *)base64String forSocketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(sendBinary:(NSString *)base64String forSocketID:(double)socketID)
{
[self sendData:[[NSData alloc] initWithBase64EncodedString:base64String options:0] forSocketID:socketID];
[self sendData:[[NSData alloc] initWithBase64EncodedString:base64String options:0] forSocketID:@(socketID)];
}

- (void)sendData:(NSData *)data forSocketID:(nonnull NSNumber *)socketID
- (void)sendData:(NSData *)data forSocketID:(NSNumber * __nonnull)socketID
{
[_sockets[socketID] send:data];
}

RCT_EXPORT_METHOD(ping:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(ping:(double)socketID)
{
[_sockets[socketID] sendPing:NULL];
[_sockets[@(socketID)] sendPing:NULL];
}

RCT_EXPORT_METHOD(close:(NSInteger)code reason:(NSString *)reason socketID:(nonnull NSNumber *)socketID)
RCT_EXPORT_METHOD(close:(double)code reason:(NSString *)reason socketID:(double)socketID)
{
[_sockets[socketID] closeWithCode:code reason:reason];
[_sockets removeObjectForKey:socketID];
[_sockets[@(socketID)] closeWithCode:code reason:reason];
[_sockets removeObjectForKey:@(socketID)];
}

- (void)setContentHandler:(id<RCTWebSocketContentHandler>)handler forSocketID:(NSString *)socketID
Expand Down Expand Up @@ -189,6 +194,11 @@ - (void)webSocket:(RCTSRWebSocket *)webSocket
}];
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return std::make_shared<facebook::react::NativeWebSocketModuleSpecJSI>(self, jsInvoker);
}

@end

@implementation RCTBridge (RCTWebSocketModule)
Expand All @@ -199,3 +209,7 @@ - (RCTWebSocketModule *)webSocketModule
}

@end

Class RCTWebSocketModuleCls(void) {
return RCTWebSocketModule.class;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public NativeWebSocketModuleSpec(ReactApplicationContext reactContext) {
}

@ReactMethod
public abstract void sendBinary(String base64String, double socketID);
public abstract void sendBinary(String base64String, double forSocketID);

@ReactMethod
public abstract void removeListeners(double count);
Expand All @@ -38,7 +38,7 @@ public NativeWebSocketModuleSpec(ReactApplicationContext reactContext) {
public abstract void close(double code, String reason, double socketID);

@ReactMethod
public abstract void send(String message, double socketID);
public abstract void send(String message, double forSocketID);

@ReactMethod
public abstract void connect(String url, ReadableArray protocols, ReadableMap options,
Expand Down

0 comments on commit d73ae1b

Please sign in to comment.