SocketServiceHandler.m 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. //
  2. // SocketServiceHandler.m
  3. // OneCable
  4. //
  5. // Created by KaRam Kim on 2017. 2. 17..
  6. // Copyright © 2017년 ntels. All rights reserved.
  7. //
  8. #import "SocketServiceHandler.h"
  9. #import "Definitions.h"
  10. #import "JDJSONModel.h"
  11. #import "JDObject.h"
  12. #define MAX_RETRY_CONNECT_COUNT 1
  13. #define MAX_REQUEST_ID 255
  14. #define NONE_DELEGATE_REQUEST_ID -99
  15. @interface SocketServiceHandler() <SRWebSocketDelegate>
  16. {
  17. SRWebSocket *_socket;
  18. NSMutableArray<SocketRequestModel *> *_messages;
  19. // NSMutableArray *_delegates;
  20. int _retryCount;
  21. BOOL _isShowLoading;
  22. int _loadingRequestId;
  23. }
  24. @property NSMutableDictionary* controllers;
  25. @property NSMutableDictionary* responses;
  26. @property int controllerId;
  27. @end
  28. @implementation SocketServiceHandler
  29. + (id)sharedManager
  30. {
  31. static SocketServiceHandler *sharedSocketServiceHandler = nil;
  32. static dispatch_once_t onceToken;
  33. dispatch_once(&onceToken, ^{
  34. sharedSocketServiceHandler = [[self alloc] init];
  35. });
  36. return sharedSocketServiceHandler;
  37. }
  38. - (id) init
  39. {
  40. self = [super init];
  41. if (self) {
  42. _isConnected = NO;
  43. _messages = [[NSMutableArray alloc] init];
  44. // _delegates = [[NSMutableArray alloc] init];
  45. _controllers = [[NSMutableDictionary alloc] init];
  46. _responses = [[NSMutableDictionary alloc] init];
  47. self.controllerId = 0;
  48. // [self socketOpen];
  49. }
  50. return self;
  51. }
  52. //- (void) initDelegate:(id<SocketServiceDelegate>) delegate
  53. //{
  54. // [self setDelegate:delegate];
  55. //}
  56. - (SRReadyState) getSocketStatus
  57. {
  58. return _socket.readyState;
  59. }
  60. - (void) socketOpen
  61. {
  62. NSLog(@"socketOpen");
  63. _strSocketURL = [NSString stringWithFormat:@"%@%@", kSocketServer, API_ROOT_PATH];
  64. NSLog(@"socketURL : %@", _strSocketURL);
  65. if( _socket != nil )
  66. {
  67. [_socket open];
  68. }
  69. else
  70. {
  71. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:_strSocketURL]];
  72. if([[JDFacade facade].loginUser authorization]!=nil)
  73. {
  74. [request setValue:[[JDFacade facade].loginUser authorization] forHTTPHeaderField:API_AUTHORIZATION_KEY];
  75. }
  76. NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
  77. #ifdef DEBUG_MODE
  78. language = @"ko";
  79. #endif
  80. [request setValue:language forHTTPHeaderField:API_LANGUAGE_KEY];
  81. NSLog(@"All Header Info : %@", request.allHTTPHeaderFields);
  82. _socket = [[SRWebSocket alloc] initWithURLRequest:request];
  83. _socket.delegate = self;
  84. [_socket open];
  85. }
  86. }
  87. - (void) open
  88. {
  89. if( !_isConnected )
  90. {
  91. if( _socket.readyState == SR_OPEN )
  92. {
  93. _isConnected = YES;
  94. }
  95. else if ( _socket.readyState == SR_CLOSED || _socket.readyState == SR_CLOSING )
  96. {
  97. [self close];
  98. _socket = nil;
  99. [self socketOpen];
  100. }
  101. }
  102. }
  103. - (void) close
  104. {
  105. if( _isConnected )
  106. {
  107. [_socket close];
  108. _socket = nil;
  109. }
  110. else
  111. {
  112. if (_socket != nil)
  113. {
  114. _socket = nil;
  115. }
  116. }
  117. _isConnected = NO;
  118. }
  119. -(void)sendRequest {
  120. _isShowLoading = YES;
  121. [[JDFacade facade] loadIndicator:YES allowUserInteraction:NO];
  122. }
  123. -(void)fisnishRequest {
  124. _isShowLoading = NO;
  125. [[JDFacade facade] loadIndicator:NO allowUserInteraction:YES];
  126. }
  127. - (void) sendData:(SocketRequestModel *)data
  128. {
  129. if(_socket.readyState == SR_OPEN)
  130. {
  131. NSLog(@"Socket Ready Send Data");
  132. NSLog(@"Send Data : %@", data);
  133. //NSLog(@"Send Param : %@", data.getSendMessage);
  134. [_socket send:data.getSendMessage];
  135. }
  136. else if ( _socket.readyState == SR_CLOSED || _socket.readyState == SR_CLOSING )
  137. {
  138. NSLog(@"Socket State is NOT Ready, Retry Process");
  139. [_messages addObject:data];
  140. [self reConnect];
  141. }
  142. else
  143. {
  144. NSLog(@"Socket NOT Ready, Retry Process");
  145. [_messages addObject:data];
  146. if(!_isConnected)
  147. {
  148. [self socketOpen];
  149. }
  150. }
  151. }
  152. - (void) sendDataWihOutDelegate:(SocketRequestModel *)data
  153. {
  154. [self sendDataWithDelegate:data modelClass:nil delegate:nil];
  155. }
  156. - (void) sendDataWithDelegate:(SocketRequestModel *)data delegate:(id)delegate
  157. {
  158. [self sendDataWithDelegate:data modelClass:nil delegate:delegate];
  159. }
  160. - (void) sendDataWithDelegate:(SocketRequestModel *)data modelClass:(Class)modelClass delegate:(id)delegate
  161. {
  162. [self sendDataWithDelegate:data modelClass:modelClass delegate:delegate isShowLoading:NO];
  163. }
  164. - (void) sendDataWithDelegate:(SocketRequestModel *)data modelClass:(Class)modelClass delegate:(id)delegate isShowLoading:(BOOL)isShowLoading
  165. {
  166. short controllerId = NONE_DELEGATE_REQUEST_ID;
  167. if (delegate) {
  168. controllerId = self.controllerId++;
  169. if (self.controllerId >= INT16_MAX) {
  170. self.controllerId = 0;
  171. }
  172. }
  173. //NSLog(@"Request Info : %@", data);
  174. data.requestId = [NSString stringWithFormat:@"%d", controllerId];
  175. //NSLog(@"Request ID : %@", data.requestId);
  176. if (delegate) {
  177. [_controllers setObject:delegate forKey:[NSNumber numberWithInt:controllerId]];
  178. }
  179. if (modelClass) {
  180. [_responses setObject:modelClass forKey:[NSNumber numberWithInt:controllerId]];
  181. }
  182. if (controllerId!=NONE_DELEGATE_REQUEST_ID && isShowLoading) {
  183. _loadingRequestId = controllerId;
  184. [self sendRequest];
  185. }
  186. [self sendData:data];
  187. }
  188. - (void)setDelegateController:(id)delegate {
  189. short controllerId = NONE_DELEGATE_REQUEST_ID;
  190. if (delegate) {
  191. controllerId = self.controllerId++;
  192. if (self.controllerId >= INT16_MAX) {
  193. self.controllerId = 0;
  194. }
  195. }
  196. if (delegate) {
  197. [_controllers setObject:delegate forKey:[NSNumber numberWithInt:controllerId]];
  198. }
  199. }
  200. - (void)removeDelegate:(id)delegate {
  201. // [_delegates removeObject:delegate];
  202. }
  203. -(void) reConnect
  204. {
  205. if(_retryCount < MAX_RETRY_CONNECT_COUNT)
  206. {
  207. _retryCount++;
  208. [self close];
  209. _socket = nil;
  210. [self socketOpen];
  211. }
  212. else
  213. {
  214. [self close];
  215. }
  216. }
  217. #pragma mark - SRWebSocketDelegate
  218. - (void)webSocketDidOpen:(SRWebSocket *)webSocket
  219. {
  220. NSLog(@"SOCKET didOpen");
  221. _retryCount = 0;
  222. // Open이 되지 않은 상태에서 전송시도한 메세지들을 발송한다.
  223. for (SocketRequestModel *data in _messages)
  224. {
  225. [self sendData:data];
  226. [_messages removeObject:data];
  227. }
  228. // for (id controller in _delegates) {
  229. // if (controller && [controller respondsToSelector:@selector(socketConnectComplete)]) {
  230. // [controller socketConnectComplete];
  231. // }
  232. // }
  233. }
  234. - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
  235. {
  236. NSLog(@"SOCKET didReceiveMessage : %@", message);
  237. NSString *errString = @"";
  238. if( message == nil || [message isEqualToString:@""] )
  239. errString = @"message empty";
  240. else
  241. {
  242. id JSONModel = nil;
  243. NSError *error = nil;
  244. NSString *JSONString = [NSString stringWithUTF8Data:[message dataUsingEncoding:NSUTF8StringEncoding]];
  245. // NSDictionary *jsonObj = [NSJSONSerialization JSONObjectWithData:[message dataUsingEncoding:NSUTF8StringEncoding]
  246. // options:NSJSONReadingAllowFragments
  247. // error:&error];
  248. //
  249. //NSLog(@"Json String : %@", JSONString);
  250. if (error != nil) {
  251. NSLog(@"NSJSONSerialization JSONObject error: %@", [error localizedDescription]);
  252. return;
  253. }
  254. SocketModel *response = [[SocketModel alloc] initWithString:JSONString error:&error];
  255. id controller = nil;
  256. Class modelClass = nil;
  257. if (response.requestId != nil && ![response.requestId isEmptyString]) {
  258. NSNumber* controllerId = [NSNumber numberWithInteger:[response.requestId integerValue]];
  259. if ([controllerId integerValue] == _loadingRequestId) {
  260. _loadingRequestId = -999;
  261. [self fisnishRequest];
  262. }
  263. controller = [self.controllers objectForKey:controllerId];
  264. modelClass = [self.responses objectForKey:controllerId];
  265. }
  266. id rawJSON = [NSJSONSerialization JSONObjectWithData:[message dataUsingEncoding:NSUTF8StringEncoding]
  267. options:NSJSONReadingAllowFragments
  268. error:&error];
  269. if (modelClass) {
  270. if ([rawJSON isKindOfClass:[NSArray class]]) {
  271. NSDictionary *JSONDic = @{@"list": rawJSON};
  272. JSONModel = [[modelClass alloc] initWithDictionary:JSONDic error:&error];
  273. }
  274. else {
  275. JSONModel = [[modelClass alloc] initWithString:JSONString error:&error];
  276. }
  277. } else {
  278. JSONModel = rawJSON;
  279. }
  280. NSLog(@"JSONModel : %@", JSONModel);
  281. //0622 공통 메세징 처리, 기존 메세징 처리 주석 LoginViewController,ThingsDetailViewController
  282. if (!response.isSuccess) [self handlingSocketErrors:response];
  283. if (!controller) {
  284. if (self.controllers.count > 0) {
  285. NSArray* array = self.controllers.allKeys;
  286. for (NSNumber *key in array) {
  287. id controller = [self.controllers objectForKey:key];
  288. if ([controller respondsToSelector:@selector(socketDidReceiveMessage:result:)]) {
  289. [controller socketDidReceiveMessage:JSONModel result:response];
  290. }
  291. }
  292. }
  293. [[NSNotificationCenter defaultCenter] postNotificationName:kSocketBoradCast object:JSONModel];
  294. }
  295. else {
  296. if ([controller respondsToSelector:@selector(socketDidReceiveMessage:result:)]) {
  297. [controller socketDidReceiveMessage:JSONModel result:response];
  298. }
  299. [self.controllers removeObjectForKey:[NSNumber numberWithInteger:[response.requestId integerValue]]];
  300. // if (self.controllers.count > 1) {
  301. // NSArray* array = self.controllers.allKeys;
  302. // NSArray* sortedArray = [array sortedArrayUsingSelector:@selector(compare:)];
  303. //
  304. // [self.controllers removeObjectForKey:[sortedArray objectAtIndex:0]];
  305. // }
  306. }
  307. NSLog(@"[socket service didReceiveMessage]");
  308. // TODO : 전달받은 데이터로 자동으로 처리할 내용이 있으면 이곳에서 처리할것
  309. // 디바이스 정보인 경우 로컬 정보를 업데이트
  310. if (response != nil && EQUALS(response.messageType, MSG_TYPE_DEVICE_CONTENT)) {
  311. [self updateDeviceContentWithJSONModel:JSONModel];
  312. }
  313. else if(response != nil && EQUALS(response.messageType, MSG_TYPE_DEVICE_CONN)) {
  314. [self updateDeviceConnectionJSONModel:JSONModel];
  315. }
  316. }
  317. }
  318. - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
  319. {
  320. NSLog(@"WebSocket error: %@", error);
  321. _isConnected = NO;
  322. [self reConnect];
  323. }
  324. - (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload
  325. {
  326. NSLog(@"WebSocket Receive Pong: %@", pongPayload);
  327. }
  328. - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean
  329. {
  330. NSLog(@"WebSocket closed with code: %ld reason:%@ wasClean:%d",
  331. (long)code, reason, wasClean);
  332. _isConnected = NO;
  333. [self reConnect];
  334. }
  335. #pragma mark - socket 통신 후 공통처리
  336. //device.content 정보 loginUser 에 반영
  337. - (void)updateDeviceContentWithJSONModel:(id)jsonModel {
  338. ContentDeviceModel *result = [[ContentDeviceModel alloc] initWithDictionary:jsonModel error:nil];
  339. // NSLog(@"updateDeviceContentWithJSONModel\nresult : %@", result);
  340. NSMutableArray *deviceList = [[JDFacade facade].loginUser.deviceList mutableCopy];
  341. for (NSInteger i=0 ; i<deviceList.count ; i++) {
  342. DeviceModel *deviceModel = [deviceList objectAtIndex:i];
  343. if (EQUALS(deviceModel.deviceId, result.deviceId)) {
  344. DeviceModel *newDeviceModel = [deviceModel copy];
  345. BOOL is = result.contentValue != nil &&
  346. EQUALS([result.contentValue objectForKey:@"online"], @"ON");
  347. // NSLog(@"online : %@", [result.contentValue objectForKey:@"online"]);
  348. // NSLog(@"online : %d", result.contentValue != nil &&
  349. // EQUALS([result.contentValue objectForKey:@"online"], @"ON"));
  350. //newDeviceModel.isDeviceOnlined = is;
  351. newDeviceModel.deviceOnline = is ? @"ON" : @"OFF";
  352. [deviceList replaceObjectAtIndex:i withObject:newDeviceModel];
  353. [[JDFacade facade].loginUser setDeviceList:deviceList];
  354. }
  355. }
  356. //NSLog(@"[socket service result]\n%@",[JDFacade facade].loginUser.deviceList);
  357. }
  358. //device.conn 정보 loginUser 에 반영
  359. - (void)updateDeviceConnectionJSONModel:(id)jsonModel {
  360. DeviceConnectionModel *result = [[DeviceConnectionModel alloc] initWithDictionary:jsonModel error:nil];
  361. NSMutableArray *deviceList = [[JDFacade facade].loginUser.deviceList mutableCopy];
  362. for (NSInteger i=0 ; i<deviceList.count ; i++) {
  363. DeviceModel *deviceModel = [deviceList objectAtIndex:i];
  364. if (EQUALS(deviceModel.deviceId, result.deviceId)) {
  365. DeviceModel *newDeviceModel = [deviceModel copy];
  366. newDeviceModel.deviceConn = result.deviceConn;
  367. newDeviceModel.deviceConnLastDatetime = result.deviceConnLastDatetime;
  368. [deviceList replaceObjectAtIndex:i withObject:newDeviceModel];
  369. [[JDFacade facade].loginUser setDeviceList:deviceList];
  370. }
  371. }
  372. }
  373. //socket통신 에러 71 login first 로그인으로 이동시킴
  374. - (void)handlingSocketErrors:(SocketModel*)response {
  375. BOOL isUpdateResult = [response.messageType isEqualToString:MSG_TYPE_NODE_PROFILE_UPDATE_RES];
  376. BOOL isLogin = [response.messageType isEqualToString:MSG_TYPE_LOGIN];
  377. BOOL isAutoLogin = [response.messageType isEqualToString:MSG_TYPE_AUTO_LOGIN];
  378. BOOL isDuplicateID = [response.messageType isEqualToString:MSG_TYPE_DUPLICATE_ID];
  379. //화면에서 따로 처리해야 하는 경우
  380. if (isUpdateResult || isLogin || isAutoLogin)
  381. return;
  382. BOOL online = YES;
  383. DeviceModel *deviceModel = [[JDFacade facade].loginUser getHomeHub];
  384. if (deviceModel != nil && !deviceModel.isDeviceOnlined) online = NO;
  385. //중복로그인
  386. if (isDuplicateID) {
  387. [[JDFacade facade] alert:@"다른 기기에서 동일한 계정으로 접속하여 로그아웃되었습니다." completionHander:^{
  388. [[JDFacade facade] logout];
  389. }];
  390. }
  391. //게이트웨이 에러
  392. else if ((EQUALS(response.resultCode, @"81") ||
  393. EQUALS(response.resultCode, @"82") ||
  394. EQUALS(response.resultCode, @"83")) && !online) {
  395. [[JDFacade facade] alert:@"게이트웨이를 확인해주세요." completionHander:^{
  396. UIViewController *vc = [CommonUtil instantiateViewControllerWithIdentifier:@"MainViewController" storyboardName:@"Main"];
  397. [JDFacade facade].mainViewController = (MainViewController *)vc;
  398. [[JDFacade facade].appDelegate.window setRootViewController:vc];
  399. }];
  400. }
  401. //공통 에러 메세지
  402. else if (response.resultMsg != nil){
  403. [[JDFacade facade] alert:response.resultMsg completionHander:^{
  404. //로그인으로 이동
  405. if (EQUALS(response.resultCode, @"71")) {
  406. [[JDFacade facade] logout];
  407. }
  408. }];
  409. }
  410. }
  411. @end