blob: 5d4ea160b8e6fec0eb83f1468633152748fd08fd [file] [log] [blame] [edit]
//
// Copyright 2018 Google LLC.
//
// 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 <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class EDOSocket;
@class EDOSocketPort;
/**
* @typedef EDOSocketConnectedBlock
* The completion block for when the connection is established.
*
* @param socket The established socket, it is nil if any error occurs.
* @param error The error why the socket fails to create if there is any.
*/
typedef void (^EDOSocketConnectedBlock)(EDOSocket *_Nullable socket, NSError *_Nullable error);
/**
* The opaque socket wrapper used to create a socket channel.
*
* User should not inspect this in any manner, only use it to create a @c EDOSocketChannel. User
* may only create one channel from one socket, and the channel will take over the ownership of the
* underlying socket and user won't be able to use it to create any other channels. The @c
* EDOSocket becomes invalid after.
*/
@interface EDOSocket : NSObject
/** The underlying socket file descriptor. */
@property(nonatomic, readonly) dispatch_fd_t socket;
/** Whether the socket is valid. */
@property(nonatomic, readonly) BOOL valid;
/** The socket port and address this socket is bound to. */
@property(nonatomic, readonly) EDOSocketPort *socketPort;
/**
* Connects to localhost on the given port asynchronously.
*
* @param port The port number.
* @param queue The queue where the completion block will be dispatched to. If @c nil, it creates a
* serial queue.
* @param block The block to be invoked after the connection is established.
*/
+ (void)connectWithTCPPort:(UInt16)port
queue:(dispatch_queue_t _Nullable)queue
connectedBlock:(EDOSocketConnectedBlock _Nullable)block;
/**
* Creates a socket that connects to the given port synchronously.
*
* @param port The port number.
* @param queue The queue where the completion block will be dispatched to. If @c nil, it creates a
* serial queue.
* @param error The error if it fails to connect.
* @return An instance of @c EDOSocket that connects to the given port, @c nil if failed.
*/
+ (nullable instancetype)socketWithTCPPort:(UInt16)port
queue:(dispatch_queue_t _Nullable)queue
error:(NSError *_Nullable *_Nullable)error;
/**
* Init with a socket descriptor.
*
* It will taking over the ownership of socket, double release or close the socket will result in a
* potential crash.
*
* @param socket The socket file descriptor.
*/
- (instancetype)initWithSocket:(dispatch_fd_t)socket NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
/** @see [EDOSocket initWithSocket:] */
+ (instancetype)socketWithSocket:(dispatch_fd_t)socket;
/**
* Release the ownership of the underlying socket and return it.
*
* It is not guaranteed to return a valid socket; it returns what the underlying socket is and
* reset it to -1, the invalid socket descriptor.
*/
- (dispatch_fd_t)releaseSocket;
/**
* Release the ownership of the underlying socket and return as a @c dispatch_io_t.
*
* @return An instance of @c dispatch_ic_t if the underlying socket is valid, @c nil otherwise.
*/
- (nullable dispatch_io_t)releaseAsDispatchIO;
/** Invalidate by closing its associated socket file descriptor. */
- (void)invalidate;
/**
* Create a @c EDOSocket listening on the given port.
*
* When a new incoming connection is accepted, the block with the new socket will be dispatched
* to the queue. The connection may drop if the user ignores and doesn't keep the socket or
* create the EDOSocketChannel. It is user's responsibility to track all the incoming connections.
*
* @param port The port number. If 0, an available port will be assigned.
* @param queue The dispatch queue that the block will be dispatched to. If @c nil, it creates a
* new concurrent queue.
* @param block The block will be dispatched when there is a new connection that is about to be
* established.
*
* @return The socket connection that listens on the port, invalidating or releasing it will
* effectively reject any new requests, but the already established connections will stay
* intact as they are maintained in a different endpoint and @c EDOSocketChannel.
*/
+ (EDOSocket *_Nullable)listenWithTCPPort:(UInt16)port
queue:(dispatch_queue_t _Nullable)queue
connectedBlock:(EDOSocketConnectedBlock _Nullable)block;
@end
NS_ASSUME_NONNULL_END