2012-11-10 32 views
0

我正在使用CocoaAsyncSocket,我需要做一個函數向服務器發送消息,並等待服務器回覆,在委託方法中它接收服務器響應,但我需要發送消息的函數等待服務器回覆並返回響應。從CocoaAsyncSocket讀取數據

- (NSString *)sendMessage:(NSString *)message{ 
    NSError *err = nil; 
    if (![socket connectToHost:@"192.168.1.20" onPort:52523 error:&err]) // Asynchronous! 
    { 
     NSLog(@"Error is : %@", err); 
    } 

    [socket readDataWithTimeout:-1 tag:1]; 

    NSData* data =[message dataUsingEncoding:NSUTF8StringEncoding]; 
    [socket writeData:data withTimeout:-1 tag:1]; 

    NSString *xmlString = [[NSString alloc] init]; 
    // Here I need the function wait and receive the response 

    return xmlString; 
} 

回答

1

如果您需要同步發送的東西,爲什麼不建立一個請求,並使用NSURLConnection的API喜歡這裏:

NSData* data = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error]; 

這將阻止,直到你得到迴應。

如果你想使用異步套接字方法來保持,但強行使其同步調用,您可以通過添加以下方法做到這一點:

@property (nonatomic, assign) BOOL com_private_condition; 
@property (nonatomic, assign) NSThread* com_private_theWaitingThread; 

...

@synthesize com_private_condition; 
@synthesize com_private_theWaitingThread; 

.. 。

- (BOOL)waitForConditionWithTimeout:(NSTimeInterval)aTimeout 
    { 
     self.com_private_condition = NO; 
     self.com_private_theWaitingThread = [NSThread currentThread]; 
     NSDate* theStartDate = [NSDate date]; 
     NSDate* theEndDate = [NSDate dateWithTimeIntervalSinceNow:aTimeout]; 
     do 
     { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
           beforeDate:theEndDate]; 
     NSTimeInterval theElapsedTime = -[theStartDate timeIntervalSinceNow]; 
     if (theElapsedTime >= aTimeout) 
     { 
      return NO; 
     } 
     if (self.com_private_condition) 
     { 
      return YES; 
     } 
    } while (YES); 
} 

- (void)signalCondition 
{ 
    [self performSelector:@selector(com_private_signalCondition:) 
       onThread:self.com_private_theWaitingThread 
       withObject:nil waitUntilDone:NO]; 
} 

- (void)com_private_signalCondition:(id)aParam 
{ 
    self.com_private_condition = YES;  
} 

現在使你的方法是這樣

在CocoaAsyncSocket回調插座
- (NSString *)sendMessage:(NSString *)message{ 
    NSError *err = nil; 
    if (![socket connectToHost:@"192.168.1.20" onPort:52523 error:&err]) // Asynchronous! 
    { 
     NSLog(@"Error is : %@", err); 
    } 

    [socket readDataWithTimeout:-1 tag:1]; 

    NSData* data =[message dataUsingEncoding:NSUTF8StringEncoding]; 
    [socket writeData:data withTimeout:-1 tag:1]; 

    //make xmlString a variable on your class and set it in your async socket callback when you get the data. once the wait is over just return it. 
    //NSString *xmlString = [[NSString alloc] init]; 
    // Here I need the function wait and receive the response 

    //call read and then wait 
    [socket readDataWithTimeout:-1 tag:1]; 
    [self waitForConditionWithTimeout:9999.0]; //or some other wait timeout of your choosing 
    //this will block until [self signalCondition] is called by your socket callbacks. 

    return self.xmlString; 
} 

現在:didReadData:withTag:插座:didDisconnectWithError:確保你叫

[self signalCondition]; 

一旦你調用該方法等待將繼續,並且您剛剛做出異步調用同步。

+0

我真的很欣賞您簡單回答的方式,您提供的解決方案非常實用,我通過套接字來完成此任務,因爲套接字在時間上更高效,我的項目需要時間效率。謝謝 –