mirror of
https://github.com/Tencent/Hippy.git
synced 2026-10-18 21:50:54 +08:00
149 lines
5.1 KiB
Objective-C
149 lines
5.1 KiB
Objective-C
/*!
|
|
* iOS SDK
|
|
*
|
|
* Tencent is pleased to support the open source community by making
|
|
* Hippy available.
|
|
*
|
|
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#import "HippyDefines.h"
|
|
#import "HippyWebSocketManager.h"
|
|
#import "HippyConvert.h"
|
|
#import "HippyUtils.h"
|
|
#import "HippySRWebSocket.h"
|
|
#import "HippyDefines.h"
|
|
|
|
static NSUInteger socketIndex = 0;
|
|
static NSString *const kHippyWebSocketUrlParamKey = @"url";
|
|
static NSString *const kHippyWebSocketHeaderParamKey = @"headers";
|
|
static NSString *const kHippySecWebSocketProtocolKey = @"Sec-WebSocket-Protocol";
|
|
|
|
#pragma mark - HippyWebSocketManager
|
|
|
|
@interface HippyWebSocketManager () <HippySRWebSocketDelegate>
|
|
|
|
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, HippySRWebSocket *> *sockets;
|
|
@property (nonatomic, strong) dispatch_queue_t queue;
|
|
|
|
@end
|
|
|
|
@implementation HippyWebSocketManager
|
|
|
|
HIPPY_EXPORT_MODULE(websocket)
|
|
|
|
- (dispatch_queue_t)methodQueue {
|
|
return _queue;
|
|
}
|
|
|
|
- (instancetype)init {
|
|
if ((self = [super init])) {
|
|
_sockets = [NSMutableDictionary new];
|
|
_queue = dispatch_queue_create("com.tencent.hippy.WebSocketManager", DISPATCH_QUEUE_SERIAL);
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)invalidate {
|
|
for (HippySRWebSocket *socket in _sockets.allValues) {
|
|
socket.delegate = nil;
|
|
[socket close];
|
|
}
|
|
}
|
|
|
|
HIPPY_EXPORT_METHOD(connect:(NSDictionary *)params resolver:(HippyPromiseResolveBlock)resolve rejecter:(HippyPromiseRejectBlock)reject) {
|
|
NSDictionary *headers = params[kHippyWebSocketHeaderParamKey];
|
|
NSString *url = params[kHippyWebSocketUrlParamKey];
|
|
NSString *protocols = headers[kHippySecWebSocketProtocolKey];
|
|
// prepare extra headers
|
|
NSMutableDictionary *extraHeaders = headers.mutableCopy;
|
|
[extraHeaders removeObjectForKey:kHippySecWebSocketProtocolKey];
|
|
NSArray<NSString *> *protocolArray = [protocols componentsSeparatedByString:@","];
|
|
HippySRWebSocket *socket = [[HippySRWebSocket alloc] initWithURL:[NSURL URLWithString:url]
|
|
extraHeaders:extraHeaders
|
|
protocols:protocolArray];
|
|
socket.delegate = self;
|
|
socket.socketID = socketIndex++;
|
|
NSNumber *socketId = @(socket.socketID);
|
|
[_sockets setObject:socket forKey:socketId];
|
|
resolve(@{@"code": @(0), @"id": socketId});
|
|
[socket open];
|
|
}
|
|
|
|
HIPPY_EXPORT_METHOD(close:(NSDictionary *)params) {
|
|
NSNumber *socketId = params[@"id"];
|
|
NSNumber *code = params[@"code"];
|
|
NSString *reason = params[@"reason"];
|
|
HippySRWebSocket *socket = [_sockets objectForKey:socketId];
|
|
if (socket) {
|
|
if (code) {
|
|
[socket closeWithCode:[code integerValue] reason:reason];
|
|
}
|
|
else {
|
|
[socket close];
|
|
}
|
|
}
|
|
}
|
|
|
|
HIPPY_EXPORT_METHOD(send:(NSDictionary *)params) {
|
|
NSNumber *socketId = params[@"id"];
|
|
NSString *data = params[@"data"];
|
|
HippySRWebSocket *socket = [_sockets objectForKey:socketId];
|
|
if (socket) {
|
|
[socket send:data];
|
|
}
|
|
}
|
|
|
|
- (void)webSocket:(HippySRWebSocket *)webSocket didReceiveMessage:(id)message {
|
|
dispatch_async(_queue, ^{
|
|
[self sendEventType:@"onMessage" socket:webSocket data:@ { @"type": @"text", @"data": message?:@"" }];
|
|
});
|
|
}
|
|
|
|
- (void)webSocketDidOpen:(HippySRWebSocket *)webSocket {
|
|
dispatch_async(_queue, ^{
|
|
[self sendEventType:@"onOpen" socket:webSocket data:@ {}];
|
|
});
|
|
}
|
|
|
|
- (void)webSocket:(HippySRWebSocket *)webSocket didFailWithError:(NSError *)error {
|
|
NSString *errString = [error localizedFailureReason];
|
|
[self sendEventType:@"onError" socket:webSocket data:@{ @"error": errString?:@"unknown reason" }];
|
|
[_sockets removeObjectForKey:@(webSocket.socketID)];
|
|
}
|
|
|
|
- (void)webSocket:(HippySRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean {
|
|
NSDictionary *data = @{ @"code": @(code), @"reason": reason?:@"unknown reason" };
|
|
[self sendEventType:@"onClose" socket:webSocket data:data];
|
|
[_sockets removeObjectForKey:@(webSocket.socketID)];
|
|
}
|
|
|
|
- (void)webSocket:(HippySRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload {
|
|
}
|
|
|
|
- (void)sendEventType:(NSString *)type socket:(HippySRWebSocket *)socket data:(id)data {
|
|
for (NSNumber *key in [_sockets allKeys]) {
|
|
HippySRWebSocket *canSocket = [_sockets objectForKey:key];
|
|
if (canSocket == socket) {
|
|
NSDictionary *params = @{ @"id": key, @"type": type, @"data": data ?: @ {} };
|
|
[self sendEvent:@"hippyWebsocketEvents" params:params];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
@end
|