我们今天来看看facebook/SocketRocket的实现方法首先这是SRWebSocket定义的一些成员变量
@property (nonatomic, weak) iddelegate;/** A dispatch queue for scheduling the delegate calls. The queue doesn't need be a serial queue. If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls. */@property (nonatomic, strong) dispatch_queue_t delegateDispatchQueue;/** An operation queue for scheduling the delegate calls. If `nil` and `delegateOperationQueue` is `nil`, the socket uses main queue for performing all delegate method calls. */@property (nonatomic, strong) NSOperationQueue *delegateOperationQueue;@property (nonatomic, readonly) SRReadyState readyState;@property (nonatomic, readonly, retain) NSURL *url;@property (nonatomic, readonly) CFHTTPMessageRef receivedHTTPHeaders;// Optional array of cookies (NSHTTPCookie objects) to apply to the connections@property (nonatomic, copy) NSArray *requestCookies;// This returns the negotiated protocol.// It will be nil until after the handshake completes.@property (nonatomic, readonly, copy) NSString *protocol;
下面这些是SRWebSocket的一些方法
// Protocols should be an array of strings that turn into Sec-WebSocket-Protocol.- (instancetype)initWithURLRequest:(NSURLRequest *)request;- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray*)protocols;- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;// Some helper constructors.- (instancetype)initWithURL:(NSURL *)url;- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray *)protocols;- (instancetype)initWithURL:(NSURL *)url protocols:(NSArray *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates;// By default, it will schedule itself on +[NSRunLoop SR_networkRunLoop] using defaultModes.- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode;// SRWebSockets are intended for one-time-use only. Open should be called once and only once.- (void)open;- (void)close;- (void)closeWithCode:(NSInteger)code reason:(NSString *)reason;///--------------------------------------#pragma mark Send///--------------------------------------//下面是4个发送的方法/** Send a UTF-8 string or binary data to the server. @param message UTF-8 String or Data to send. @deprecated Please use `sendString:` or `sendData` instead. */- (void)send:(id)message __attribute__((deprecated("Please use `sendString:` or `sendData` instead.")));- (void)sendString:(NSString *)string;- (void)sendData:(NSData *)data;- (void)sendPing:(NSData *)data;@end
对应5种状态的代理方法
///--------------------------------------#pragma mark - SRWebSocketDelegate///--------------------------------------@protocol SRWebSocketDelegate- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message;@optional- (void)webSocketDidOpen:(SRWebSocket *)webSocket;- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error;- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean;- (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload;// Return YES to convert messages sent as Text to an NSString. Return NO to skip NSData -> NSString conversion for Text messages. Defaults to YES.- (BOOL)webSocketShouldConvertTextFrameToString:(SRWebSocket *)webSocket;@end
didReceiveMessage方法是必须实现的,用来接收消息的。下面4个did方法分别对应着Open,Fail,Close,ReceivePong不同状态的代理方法
方法就上面这些了,我们实际来看看代码怎么写
先是初始化Websocket连接,注意此处ws://或者wss://连接有且最多只能有一个,这个是Websocket协议规定的
self.ws = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@://%@:%zd/ws", serverProto, serverIP, serverPort]]]]; self.ws.delegate = delegate; [self.ws open];
发送消息
[self.ws send:message];
接收消息以及其他3个代理方法
//这个就是接受消息的代理方法了,这里接受服务器返回的数据,方法里面就应该写处理数据,存储数据的方法了。- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message{ NSDictionary *data = [NetworkUtils decodeData:message]; if (!data) return;}//这里是Websocket刚刚Open之后的代理方法。就想微信刚刚连接中,会显示连接中,当连接上了,就不显示连接中了,取消显示连接的方法就应该写在这里面- (void)webSocketDidOpen:(SRWebSocket *)webSocket{ // Open = silent ping [self.ws receivedPing];}//这是关闭Websocket的代理方法- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean{ [self failedConnection:NSLS(Disconnected)];}//这里是连接Websocket失败的方法,这里面一般都会写重连的方法- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error{ [self failedConnection:NSLS(Disconnected)];}