// // SocketServiceHandler.m // OneCable // // Created by KaRam Kim on 2017. 2. 17.. // Copyright © 2017년 ntels. All rights reserved. // #import "SocketServiceHandler.h" #import #import "Definitions.h" @interface SocketServiceHandler() { SRWebSocket *_socket; NSMutableArray *_messages; } @end @implementation SocketServiceHandler + (id)sharedManager { static SocketServiceHandler *sharedSocketServiceHandler = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedSocketServiceHandler = [[self alloc] init]; }); return sharedSocketServiceHandler; } - (id) init { self = [super init]; if (self) { _isConnected = NO; // // _socket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:_strSocketURL]]; // _socket.delegate = self; _messages = [[NSMutableArray alloc] init]; [self socketOpen]; } return self; } - (void) initWithDelegate:(id) delegate { [self setDelegate:delegate]; } - (void) socketOpen { NSLog(@"socketOpen"); _strSocketURL = [NSString stringWithFormat:@"%@%@", kSocketServer, API_ROOT_PATH]; NSLog(@"socketURL : %@", _strSocketURL); if( _socket != nil ) [_socket open]; else { _socket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:_strSocketURL]]; _socket.delegate = self; [_socket open]; } } - (void) open { if( !_isConnected ) { if( _socket.readyState == SR_OPEN ) { _isConnected = YES; } else if ( _socket.readyState == SR_CLOSED || _socket.readyState == SR_CLOSING ) { [self close]; _socket = nil; [self socketOpen]; } } } - (void) close { if( _isConnected ) { [_socket close]; _socket = nil; } } - (void) sendData:(NSDictionary *)data { // if(!_isConnected) // { // [_messages addObject:data]; // [self socketOpen]; // } if(_socket.readyState == SR_OPEN) { NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string error:&error]; if (!jsonData) { NSLog(@"Got an error: %@", error); } else { NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSLog(@"Socket Send Data : %@", jsonString); [_socket send:jsonString]; } } else if ( _socket.readyState == SR_CLOSED || _socket.readyState == SR_CLOSING ) { // TODO : 미전송 메세지 저장하고 있기 [_messages addObject:data]; [self reConnect]; } else { [_messages addObject:data]; } } -(void) reConnect { [self close]; _socket = nil; [self socketOpen]; } #pragma mark - SRWebSocketDelegate - (void)webSocketDidOpen:(SRWebSocket *)webSocket { NSLog(@"SOCKET didOpen"); // Open이 되지 않은 상태에서 전송시도한 메세지들을 발송한다. for (NSDictionary *data in _messages) { [self sendData:data]; [_messages removeObject:data]; } if (self.delegate && [self.delegate respondsToSelector:@selector(socketConnectComplete)]) { [self.delegate socketConnectComplete]; } } - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message { NSLog(@"SOCKET didReceiveMessage : %@", message); if (self.delegate && [self.delegate respondsToSelector:@selector(didReceiveMessage:)]) { [self.delegate didReceiveMessage:message]; } NSString *errString = @""; if( message == nil || [message isEqualToString:@""] ) errString = @"message empty"; else { if( [message isKindOfClass:[NSString class]] ) { NSError* error = nil; NSDictionary *jsonObj = [NSJSONSerialization JSONObjectWithData:[message dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error]; if (error != nil) { NSLog(@"NSJSONSerialization JSONObject error: %@", [error localizedDescription]); return; } NSInteger msgType = [jsonObj[@"type"] integerValue]; if ( msgType == 0 ) { } else { NSLog(@"msgType : %i",(int)msgType); } } } } - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error { NSLog(@"WebSocket error: %@", error); _isConnected = NO; [self reConnect]; } - (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload { NSLog(@"WebSocket Receive Pong: %@", pongPayload); } - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean { NSLog(@"WebSocket closed with code: %ld reason:%@ wasClean:%d", (long)code, reason, wasClean); _isConnected = NO; [self reConnect]; } @end